/*****************************************************************************/ /* */ /* 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 #include #include #include /* */ /* 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%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