Files
SaraP 739088af9f Vroni 7.8 :
- aggiornamento versione.
2025-01-29 16:24:30 +01:00

728 lines
20 KiB
C++

/*****************************************************************************/
/* */
/* Copyright (C) 1999-2025 M. Held */
/* */
/* This code is not in the public domain. All rights reserved! Please make */
/* sure to read the full copyright statement contained in "README.txt" or in */
/* the "main" file of this code, such as "main.cc". */
/* */
/*****************************************************************************/
/* */
/* Written by: Martin Held */
/* */
/* E-Mail: held@cs.sbg.ac.at */
/* Fax Mail: (+43 662) 8044-611 */
/* Voice Mail: (+43 662) 8044-6304 */
/* Snail Mail: Martin Held */
/* FB Informatik */
/* Universitaet Salzburg */
/* A-5020 Salzburg, Austria */
/* */
/*****************************************************************************/
/* */
/* get standard libraries */
/* */
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <math.h>
/* */
/* get my header files */
/* */
#include "fpkernel.h"
#include "vronivector.h"
#include "vroni_object.h"
#include "defs.h"
#include "numerics.h"
#include "ipe_io.h"
#ifdef GRAPHICS
#define MINI 32
#define BLOCK_SIZE 1024
#define PAGE_SIZE 65536
void vroniObject::ResetBufferData(void)
{
num_pnt_buf = 0;
num_seg_buf = 0;
num_arc_buf = 0;
num_vde_buf = 0;
num_vdn_buf = 0;
num_off_buf = 0;
num_cur_buf = 0;
num_cir_buf = 0;
return;
}
void vroniObject::ResetOffsetBuffer(void)
{
num_off_buf = 0;
num_cur_buf = 0;
return;
}
void vroniObject::ResetCurBuffer(void)
{
num_cur_buf = 0;
return;
}
void vroniObject::ResetVDBuffer(void)
{
num_vde_buf = 0;
num_vdn_buf = 0;
return;
}
void vroniObject::AddNodeToBuffer(int index, int color)
{
if (num_vdn_buf >= max_num_vdn_buf) {
max_num_vdn_buf += BLOCK_SIZE;
vdn_buf = (buffer*) ReallocateArray(vdn_buf, max_num_vdn_buf,
sizeof(buffer), "redraw:vdn_buf");
}
vdn_buf[num_vdn_buf].index = index;
vdn_buf[num_vdn_buf].color = color;
++num_vdn_buf;
return;
}
void vroniObject::AddPntToBuffer(int index, int color)
{
if (num_pnt_buf >= max_num_pnt_buf) {
max_num_pnt_buf += BLOCK_SIZE;
pnt_buf = (buffer*) ReallocateArray(pnt_buf, max_num_pnt_buf,
sizeof(buffer), "redraw:pnt_buf");
}
pnt_buf[num_pnt_buf].index = index;
pnt_buf[num_pnt_buf].color = color;
++num_pnt_buf;
return;
}
void vroniObject::AddSegToBuffer(int index, int color)
{
if (num_seg_buf >= max_num_seg_buf) {
max_num_seg_buf += BLOCK_SIZE;
seg_buf = (buffer*) ReallocateArray(seg_buf, max_num_seg_buf,
sizeof(buffer), "redraw:seg_buf");
}
seg_buf[num_seg_buf].index = index;
seg_buf[num_seg_buf].color = color;
++num_seg_buf;
return;
}
void vroniObject::AddArcToBuffer(int index, int color)
{
if (num_arc_buf >= max_num_arc_buf) {
max_num_arc_buf += BLOCK_SIZE;
arc_buf = (buffer*) ReallocateArray(arc_buf, max_num_arc_buf,
sizeof(buffer), "redraw:arc_buf");
}
arc_buf[num_arc_buf].index = index;
arc_buf[num_arc_buf].color = color;
++num_arc_buf;
return;
}
// MODIF : aggiunti anche i parametri dPar1 e dPar2 in cui vengono calcolati i due punti (x1, y1) ( x2, y2)
void vroniObject::AddEdgeToBuffer(double_arg x1, double_arg y1,
double_arg x2, double_arg y2, int color)
{
AddEdgeToBuffer( x1, y1, x2, y2, color, -1.0, -1.0) ;
}
void vroniObject::AddEdgeToBuffer(double_arg x1, double_arg y1,
double_arg x2, double_arg y2, int color, double dPar1, double dPar2)
{
if (num_vde_buf >= max_num_vde_buf) {
// MODIF modifico quantità di memoria richiesta dall'allocazione in analogia con std::vector
// max_num_vde_buf += PAGE_SIZE;
max_num_vde_buf = ( num_vde_buf + 1) * 2;
gentlyResizeSTLVector(vde_buf, max_num_vde_buf, "redraw:vde_buf");
}
vde_buf[num_vde_buf].p1.x = x1;
vde_buf[num_vde_buf].p1.y = y1;
vde_buf[num_vde_buf].p2.x = x2;
vde_buf[num_vde_buf].p2.y = y2;
vde_buf[num_vde_buf].color = color;
vde_buf[num_vde_buf].dPar1 = dPar1 ;
vde_buf[num_vde_buf].dPar2 = dPar2 ;
++num_vde_buf;
/*
if (color == WMATColor) {
printf("0\n%20.16f %20.16f %20.16f %20.16f\n", x1, y1, x2, y2);
}
*/
return;
}
void vroniObject::AddOffToBuffer(double_arg x1, double_arg y1,
double_arg x2, double_arg y2,
double_arg x3, double_arg y3,
double_arg r, vr_bool ccw, int color)
{
if (num_off_buf >= max_num_off_buf) {
max_num_off_buf += PAGE_SIZE;
gentlyResizeSTLVector(off_buf, max_num_off_buf, "redraw:off_buf");
}
off_buf[num_off_buf].p1.x = x1;
off_buf[num_off_buf].p1.y = y1;
off_buf[num_off_buf].p2.x = x2;
off_buf[num_off_buf].p2.y = y2;
off_buf[num_off_buf].p3.x = x3;
off_buf[num_off_buf].p3.y = y3;
off_buf[num_off_buf].r = r;
off_buf[num_off_buf].ccw = ccw;
off_buf[num_off_buf].color = color;
++num_off_buf;
return;
}
void vroniObject::AddCirToBuffer(coord cntr, double_arg radius)
{
if (num_cir_buf >= max_num_cir_buf) {
max_num_cir_buf += PAGE_SIZE;
gentlyResizeSTLVector(cir_buf, max_num_cir_buf, "redraw:cir_buf");
}
cir_buf[num_cir_buf].cntr = cntr;
cir_buf[num_cir_buf].radius = radius;
++num_cir_buf;
return;
}
void vroniObject::AddDskToBuffer(coord cntr, double_arg radius)
{
if (num_dsk_buf >= max_num_dsk_buf) {
max_num_dsk_buf += PAGE_SIZE;
gentlyResizeSTLVector(dsk_buf, max_num_dsk_buf, "redraw:dsk_buf");
}
dsk_buf[num_dsk_buf].cntr = cntr;
dsk_buf[num_dsk_buf].radius = radius;
++num_dsk_buf;
return;
}
void vroniObject::FreeDrawingBuffer(void)
{
FreeMemory((void**) &arc_buf, "redraw:arc_buf");
FreeMemory((void**) &seg_buf, "redraw:seg_buf");
FreeMemory((void**) &pnt_buf, "redraw:pnt_buf");
vde_buf.clear();
off_buf.clear();
cir_buf.clear();
dsk_buf.clear();
FreeMemory((void**) &vdn_buf, "redraw:vdn_buf");
FreeMemory((void**) &cur_buf, "redraw:cur_buf");
num_dsk_buf = 0;
num_cir_buf = 0;
num_cur_buf = 0;
num_vde_buf = 0;
num_off_buf = 0;
num_vdn_buf = 0;
num_pnt_buf = 0;
num_seg_buf = 0;
num_arc_buf = 0;
max_num_cir_buf = 0;
max_num_dsk_buf = 0;
max_num_cur_buf = 0;
max_num_vde_buf = 0;
max_num_off_buf = 0;
max_num_vdn_buf = 0;
max_num_pnt_buf = 0;
max_num_seg_buf = 0;
max_num_arc_buf = 0;
return;
}
void vroniObject::UpdateBuffer(void)
{
int i, number;
ResetBufferData();
for (i = 0; i < num_pnts; ++i) {
AddPntToBuffer(i, PntColor);
}
for (i = 0; i < num_segs; ++i)
AddSegToBuffer(i, SegColor);
number = num_arcs;
for (i = 0; i < number; ++i)
AddArcToBuffer(i, SegColor);
return;
}
void vroniObject::AddToCurBuffer(int index, t_site type, int color)
{
if (num_cur_buf >= max_num_cur_buf) {
max_num_cur_buf += BLOCK_SIZE;
cur_buf = (cur_buffer*) ReallocateArray(cur_buf, max_num_cur_buf,
sizeof(cur_buffer),
"redraw:cur_buf");
}
cur_buf[num_cur_buf].index = index;
cur_buf[num_cur_buf].type = type;
cur_buf[num_cur_buf].color = color;
++num_cur_buf;
return;
}
/* */
/* this function writes the input data and the VD to a file in the */
/* Ipe 7 Xml Format. */
/* */
void vroniObject::WriteIpeOutput(char *filename)
{
int i;
coord p1, p2, p3;
FILE *fp;
fp = InitIpe(filename, bb_min.x, bb_max.x, bb_min.y, bb_max.y);
if (draw_segs || draw_arcs) WriteBeginGroup(fp, 0);
if (draw_arcs) {
for (i = 0; i < num_arc_buf; ++i) {
if (!incremental || arcs[arc_buf[i].index].draw) {
p3 = GetArcCenter(arc_buf[i].index);
p1 = GetArcStartCoord(arc_buf[i].index);
p2 = GetArcEndCoord(arc_buf[i].index);
WriteCircularArc(fp, p3.x, p3.y, p1.x, p1.y, p2.x, p2.y, true);
}
}
}
if (draw_segs) {
for (i = 0; i < num_seg_buf; ++i) {
if (!incremental || segs[seg_buf[i].index].draw) {
p1 = GetSegStartCoord(seg_buf[i].index);
p2 = GetSegEndCoord(seg_buf[i].index);
WriteLineSegment(fp, p1.x, p1.y, p2.x, p2.y);
}
}
}
if (draw_segs || draw_arcs) WriteEndGroup(fp);
if (draw_vde) {
WriteBeginGroup(fp, 1);
for (i = 0; i < num_vde_buf; ++i) {
if (vde_buf[i].color == VDColor)
WriteLineSegment(fp,
vde_buf[i].p1.x, vde_buf[i].p1.y,
vde_buf[i].p2.x, vde_buf[i].p2.y);
}
WriteEndGroup(fp);
}
if (draw_dte) {
WriteBeginGroup(fp, 3);
for (i = 0; i < num_vde_buf; ++i) {
if (vde_buf[i].color == DTColor)
WriteLineSegment(fp,
vde_buf[i].p1.x, vde_buf[i].p1.y,
vde_buf[i].p2.x, vde_buf[i].p2.y);
}
WriteEndGroup(fp);
}
if (draw_off) {
WriteBeginGroup(fp, 4);
for (i = 0; i < num_off_buf; ++i) {
if (off_buf[i].r == 0) {
WriteLineSegment(fp,
off_buf[i].p1.x, off_buf[i].p1.y,
off_buf[i].p2.x, off_buf[i].p2.y);
}
else {
WriteCircularArc(fp,
off_buf[i].p3.x, off_buf[i].p3.y,
off_buf[i].p1.x, off_buf[i].p1.y,
off_buf[i].p2.x, off_buf[i].p2.y,
!off_buf[i].ccw);
}
}
WriteEndGroup(fp);
if (draw_tool) {
if (num_dsk_buf > 0) {
WriteBeginGroup(fp, 8);
for (i = 1; i < num_dsk_buf; ++i) {
WriteCircle(fp,
dsk_buf[i].cntr.x,
dsk_buf[i].cntr.y,
dsk_buf[i].radius);
}
WriteEndGroup(fp);
}
}
}
if (draw_mat) {
WriteBeginGroup(fp, 2);
for (i = 0; i < num_vde_buf; ++i) {
if (vde_buf[i].color == WMATColor)
WriteLineSegment(fp,
vde_buf[i].p1.x, vde_buf[i].p1.y,
vde_buf[i].p2.x, vde_buf[i].p2.y);
}
WriteEndGroup(fp);
}
if (draw_mic) {
if (num_cir_buf == 1) {
WriteBeginGroup(fp, 5);
WriteCircle(fp,
cir_buf[0].cntr.x,
cir_buf[0].cntr.y,
cir_buf[0].radius);
/*
WriteCircularArc(fp,
cir_buf[0].cntr.x,
cir_buf[0].cntr.y,
cir_buf[0].cntr.x,
cir_buf[0].cntr.y - cir_buf[0].radius,
cir_buf[0].cntr.x,
cir_buf[0].cntr.y + cir_buf[0].radius, true);
WriteCircularArc(fp,
cir_buf[0].cntr.x,
cir_buf[0].cntr.y,
cir_buf[0].cntr.x,
cir_buf[0].cntr.y + cir_buf[0].radius,
cir_buf[0].cntr.x,
cir_buf[0].cntr.y - cir_buf[0].radius, true);
*/
WriteEndGroup(fp);
}
}
if (draw_vde && draw_vdn) {
WriteBeginGroup(fp, 7);
for (i = 0; i < num_vdn_buf; ++i) {
WriteMark(fp, 2, 6,
nodes[vdn_buf[i].index].p.x, nodes[vdn_buf[i].index].p.y);
}
WriteEndGroup(fp);
}
if (draw_pnts) {
WriteBeginGroup(fp, 6);
for (i = 2; i < num_pnt_buf - 2; ++i) {
assert(InPntsList(pnt_buf[i].index));
if (!incremental || pnts[pnt_buf[i].index].draw)
WriteMark(fp, 2, 6,
pnts[pnt_buf[i].index].p.x, pnts[pnt_buf[i].index].p.y);
}
WriteEndGroup(fp);
}
CloseIpeFile(fp);
return;
}
#ifdef OGL_GRAPHICS
void vroniObject::BuffToDrawArc(int j, int color)
{
assert(InArcsList(j));
assert(InPntsList(arcs[j].i1));
assert(InPntsList(arcs[j].i2));
DrawArc(GetArcStartCoord(j), GetArcEndCoord(j), GetArcCenter(j),
GetArcRadius(j), color);
coord pos;
coord norm;
pos.x = GetArcStartCoord(j).x - GetArcEndCoord(j).x;
pos.y = GetArcStartCoord(j).y - GetArcEndCoord(j).y;
norm = VecCCW(pos);
norm.x /= VecLen(pos);
norm.y /= VecLen(pos);
pos.x = GetArcCenter(j).x + norm.x*GetArcRadius(j);
pos.y = GetArcCenter(j).y + norm.y*GetArcRadius(j);
int s, e;
s = Get1stVtxArc(j);
e = Get2ndVtxArc(j);
DrawText(pos, color, " a%d %d->%d", j, s,e);
return;
}
void vroniObject::BuffToDrawSeg(int j, int color)
{
assert(InSegsList(j));
assert(InPntsList(segs[j].i1));
assert(InPntsList(segs[j].i2));
DrawSeg(GetSegStartCoord(j), GetSegEndCoord(j), color);
coord pos;
pos = MidPoint(GetSegStartCoord(j), GetSegEndCoord(j));
int s, e;
s = Get1stVtxSeg(j);
e = Get2ndVtxSeg(j);
DrawText(pos, color, " s%d %d->%d", j, s, e);
return;
}
void vroniObject::Redraw(void)
{
int i;
for (i = 0; i < num_vde_buf; ++i) {
if (vde_buf[i].color == GridColor) {
DrawSeg(vde_buf[i].p1, vde_buf[i].p2, GridColor);
}
else if (vde_buf[i].color == TreeColor) {
DrawSeg(vde_buf[i].p1, vde_buf[i].p2, TreeColor);
}
}
/*
if (num_cir_buf == 1) DrawCircle(circle_cntr, circle_radius, CirColor);
*/
if (draw_vde) {
for (i = 0; i < num_vde_buf; ++i) {
if (vde_buf[i].color == VDColor) {
DrawSeg(vde_buf[i].p1, vde_buf[i].p2, vde_buf[i].color);
}
}
if (draw_mic) {
for (i = 0; i < num_vde_buf; ++i) {
if (vde_buf[i].color == CirColor)
DrawSeg(vde_buf[i].p1, vde_buf[i].p2, vde_buf[i].color);
}
}
}
if (draw_mat) {
for (i = 0; i < num_vde_buf; ++i) {
if (vde_buf[i].color == WMATColor)
DrawSeg(vde_buf[i].p1, vde_buf[i].p2, vde_buf[i].color);
}
}
if (draw_dte) {
for (i = 0; i < num_vde_buf; ++i) {
if (vde_buf[i].color == DTColor)
DrawSeg(vde_buf[i].p1, vde_buf[i].p2, vde_buf[i].color);
}
}
if (draw_off) {
for (i = 0; i < num_off_buf; ++i) {
if (off_buf[i].r == 0.0) {
DrawSeg(off_buf[i].p1, off_buf[i].p2, off_buf[i].color);
}
else {
if (off_buf[i].ccw)
DrawArc(off_buf[i].p2, off_buf[i].p1, off_buf[i].p3,
off_buf[i].r, off_buf[i].color);
else
DrawArc(off_buf[i].p1, off_buf[i].p2, off_buf[i].p3,
off_buf[i].r, off_buf[i].color);
}
}
if (draw_tool) {
for (i = 0; i < num_dsk_buf; ++i) {
DrawCircle(dsk_buf[i].cntr, dsk_buf[i].radius, TOOLColor);
}
}
}
if (draw_arcs) {
for (i = 0; i < num_arc_buf; ++i) {
if (arcs[arc_buf[i].index].draw)
BuffToDrawArc(arc_buf[i].index, arc_buf[i].color);
else if (!incremental)
BuffToDrawArc(arc_buf[i].index, arc_buf[i].color);
}
}
if (draw_segs && draw_arcs) {
for (i = 0; i < num_seg_buf; ++i) {
if ((!incremental || segs[seg_buf[i].index].draw) &&
seg_buf[i].color == SegColor)
BuffToDrawSeg(seg_buf[i].index, seg_buf[i].color);
}
}
else if (draw_segs) {
for (i = 0; i < num_seg_buf; ++i) {
if (!incremental || segs[seg_buf[i].index].draw)
BuffToDrawSeg(seg_buf[i].index, seg_buf[i].color);
}
}
for (i = 0; i < num_cur_buf; ++i) {
switch(cur_buf[i].type) {
case(SEG):
assert(InSegsList(cur_buf[i].index));
BuffToDrawSeg(cur_buf[i].index, cur_buf[i].color);
break;
case(ARC):
assert(InArcsList(cur_buf[i].index));
BuffToDrawArc(cur_buf[i].index, cur_buf[i].color);
break;
case(VDE):
assert(InEdgesList(cur_buf[i].index));
if (draw_vde && (cur_buf[i].color == VDColor))
DrawSeg(nodes[edges[cur_buf[i].index].n1].p,
nodes[edges[cur_buf[i].index].n2].p, cur_buf[i].color);
else if (draw_mat && (cur_buf[i].color == WMATColor))
DrawSeg(nodes[edges[cur_buf[i].index].n1].p,
nodes[edges[cur_buf[i].index].n2].p, cur_buf[i].color);
break;
case(DTE):
assert(InPntsList(edges[cur_buf[i].index].n1));
assert(InPntsList(edges[cur_buf[i].index].n2));
DrawSeg(pnts[edges[cur_buf[i].index].n1].p,
pnts[edges[cur_buf[i].index].n2].p, cur_buf[i].color);
break;
default:
break;
}
}
if (draw_vde && draw_vdn) {
for (i = 0; i < num_vdn_buf; ++i) {
DrawPnt(nodes[vdn_buf[i].index].p, vdn_buf[i].color, true);
DrawText(nodes[vdn_buf[i].index].p, vdn_buf[i].color, " n%d",
vdn_buf[i].index);
}
}
if (draw_pnts) {
for (i = 0; i < num_pnt_buf; ++i) {
assert(InPntsList(pnt_buf[i].index));
if (!incremental ||
(pnts[pnt_buf[i].index].draw && !pnts[pnt_buf[i].index].del)) {
DrawPnt(pnts[pnt_buf[i].index].p, pnt_buf[i].color, false);
DrawText(pnts[pnt_buf[i].index].p, pnt_buf[i].color, " p%d",
pnt_buf[i].index);
}
}
}
else if (GetVDStatus() && !incremental) {
for (i = 0; i < num_pnt_buf; ++i) {
assert(InPntsList(pnt_buf[i].index));
if (!HasIncidentSite(pnt_buf[i].index) &&
!IsDeletedPnt(pnt_buf[i].index)) {
DrawPnt(pnts[pnt_buf[i].index].p, pnt_buf[i].color, false);
}
DrawText(pnts[pnt_buf[i].index].p, pnt_buf[i].color, " p%d",
pnt_buf[i].index);
}
}
for (i = 0; i < num_cur_buf; ++i) {
switch(cur_buf[i].type) {
case(PNT):
assert(InPntsList(cur_buf[i].index));
DrawPnt(pnts[cur_buf[i].index].p, cur_buf[i].color, true);
break;
case(VDN):
assert(InNodesList(cur_buf[i].index));
if ((draw_vde && (cur_buf[i].color != MICColor)) ||
(draw_mic && (cur_buf[i].color == MICColor)))
DrawPnt(nodes[cur_buf[i].index].p, cur_buf[i].color, true);
break;
default:
break;
}
}
if (draw_mic) {
for (i = 0; i < num_cir_buf; ++i) {
DrawCircle(cir_buf[i].cntr, cir_buf[i].radius, MICColor);
}
}
for(i=0; i<GetNumberOfEdges(); i++) {
coord pos;
pos = MidPoint(nodes[edges[i].n1].p, nodes[edges[i].n2].p);
DrawText(pos, VDColor, " e%d (%d>%d)", i, edges[i].n1, edges[i].n2);
}
if (!(draw_pnts || draw_segs || draw_arcs || draw_vde))
VD_Warning("Redraw() - draw at least points or segs?");
return;
}
#endif /* OGL_GRAPHICS */
#include "ext_appl_redraw.cc"
#endif