0029304: Draw Harness, DBRep_DrawableShape - fix inappropriate use of unordered map
[occt.git] / src / DBRep / DBRep_DrawableShape.cxx
CommitLineData
b311480e 1// Created on: 1991-07-04
2// Created by: Christophe MARION
3// Copyright (c) 1991-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
7fd59977 17
42cf5bc1 18#include <Adaptor3d_HCurve.hxx>
19#include <BRep_Tool.hxx>
20#include <BRepAdaptor_Curve.hxx>
21#include <BRepAdaptor_Surface.hxx>
22#include <BRepMesh_IncrementalMesh.hxx>
23#include <BRepTools.hxx>
24#include <DBRep_DrawableShape.hxx>
7fd59977 25#include <DBRep_Edge.hxx>
42cf5bc1 26#include <DBRep_Face.hxx>
27#include <DBRep_HideData.hxx>
7fd59977 28#include <DBRep_IsoBuilder.hxx>
7fd59977 29#include <DBRep_ListIteratorOfListOfEdge.hxx>
42cf5bc1 30#include <DBRep_ListIteratorOfListOfFace.hxx>
7fd59977 31#include <DBRep_ListIteratorOfListOfHideData.hxx>
42cf5bc1 32#include <Draw_Appli.hxx>
33#include <Draw_Color.hxx>
34#include <Draw_Display.hxx>
35#include <Draw_Drawable3D.hxx>
36#include <Geom_BSplineCurve.hxx>
37#include <Geom_BSplineSurface.hxx>
38#include <GeomAdaptor_HSurface.hxx>
39#include <GeomAdaptor_Surface.hxx>
7fd59977 40#include <gp_Lin2d.hxx>
41#include <gp_Trsf.hxx>
42cf5bc1 42#include <HLRBRep.hxx>
43#include <Poly_Connect.hxx>
7fd59977 44#include <Poly_Polygon3D.hxx>
7fd59977 45#include <Poly_PolygonOnTriangulation.hxx>
42cf5bc1 46#include <Poly_Triangulation.hxx>
7fd59977 47#include <Precision.hxx>
42cf5bc1 48#include <Standard_DomainError.hxx>
49#include <Standard_Type.hxx>
50#include <TColgp_HArray1OfPnt.hxx>
7fd59977 51#include <TColStd_DataMapIteratorOfDataMapOfIntegerInteger.hxx>
42cf5bc1 52#include <TColStd_DataMapOfIntegerInteger.hxx>
53#include <TColStd_HArray1OfInteger.hxx>
54#include <TopExp.hxx>
55#include <TopExp_Explorer.hxx>
56#include <TopoDS.hxx>
57#include <TopoDS_Edge.hxx>
58#include <TopoDS_Face.hxx>
59#include <TopoDS_Shape.hxx>
60#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
61#include <TopTools_ListOfShape.hxx>
7fd59977 62
92efcf78 63IMPLEMENT_STANDARD_RTTIEXT(DBRep_DrawableShape,Draw_Drawable3D)
64
7fd59977 65static Standard_Real IsoRatio = 1.001;
66
67static Standard_Integer MaxPlotCount = 5; // To avoid huge recursive calls in
68static Standard_Integer PlotCount = 0; // PlotEdge and PlotIso for cases of "bad"
69 // curves and surfaces
70 // Set PlotCount = 0 before first call of
71 // PlotEdge or PlotIso
72static TopoDS_Shape pickshape;
73static Standard_Real upick,vpick;
57c28b61 74#ifdef _WIN32
7fd59977 75extern Draw_Viewer dout;
76#endif
77
78//=======================================================================
79//function : DBRep_DrawableShape
80//purpose : constructor
81//=======================================================================
82
83DBRep_DrawableShape::DBRep_DrawableShape
84 (const TopoDS_Shape& aShape,
85 const Draw_Color& FreeCol,
86 const Draw_Color& ConnCol,
87 const Draw_Color& EdgeCol,
88 const Draw_Color& IsosCol,
89 const Standard_Real size,
90 const Standard_Integer nbisos,
91 const Standard_Integer discret) :
92 mySize(size),
93 myDiscret(discret),
94 myFreeCol(FreeCol),
95 myConnCol(ConnCol),
96 myEdgeCol(EdgeCol),
97 myIsosCol(IsosCol),
98 myNbIsos(nbisos),
99 myDispOr(Standard_False),
100 mytriangulations(Standard_False),
101 mypolygons(Standard_False),
102 myHLR(Standard_False),
103 myRg1(Standard_False),
104 myRgN(Standard_False),
105 myHid(Standard_False)
106{
6662fe63 107 myShape = aShape;
7fd59977 108}
109
110//=======================================================================
6662fe63 111//function : updateDisplayData
7fd59977 112//purpose :
113//=======================================================================
114
6662fe63 115void DBRep_DrawableShape::updateDisplayData () const
7fd59977 116{
7fd59977 117 myFaces.Clear();
118 myEdges.Clear();
119
120 if (myShape.IsNull())
121 return;
122
123 //==============================================================
124 // Process the faces
125 //==============================================================
126
127 TopExp_Explorer ExpFace;
128 TopLoc_Location l;
129
130 for (ExpFace.Init (myShape,TopAbs_FACE);
131 ExpFace.More();
132 ExpFace.Next()) {
133 TopoDS_Face TopologicalFace = TopoDS::Face (ExpFace.Current());
134 if(myNbIsos != 0) {
135 const Handle(Geom_Surface)& S =
136 BRep_Tool::Surface(TopologicalFace,l);
137 if (!S.IsNull()) {
138 TopologicalFace.Orientation (TopAbs_FORWARD) ;
139 DBRep_IsoBuilder IsoBuild (TopologicalFace, mySize, myNbIsos) ;
140 myFaces.Append(new DBRep_Face (TopologicalFace,
141 IsoBuild.NbDomains(),
142 myIsosCol)) ;
143 IsoBuild.LoadIsos (myFaces.Last()) ;
144 }
145 else myFaces.Append(new DBRep_Face(TopologicalFace,0, myEdgeCol));
146 }
147 else myFaces.Append(new DBRep_Face(TopologicalFace,0, myEdgeCol));
148 }
149
150 //==============================================================
151 // process a 3D edge
152 //==============================================================
153
154 TopTools_IndexedDataMapOfShapeListOfShape edgemap;
6662fe63 155 TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,edgemap);
7fd59977 156 Standard_Integer iedge;
157
158 for (iedge = 1; iedge <= edgemap.Extent(); iedge++) {
159
160 const TopoDS_Edge& theEdge = TopoDS::Edge(edgemap.FindKey(iedge));
161
162 // skip degenerated edges
163 if (BRep_Tool::Degenerated(theEdge)) continue;
164
165 // compute the number of faces
166 Standard_Integer nbf = edgemap(iedge).Extent();
167
168 Draw_Color EdgeColor;
169
170 switch (nbf) {
171
172 case 0 :
173 EdgeColor = myEdgeCol; // isolated edge
174 break;
175
176 case 1 :
177 EdgeColor = myFreeCol; // edge in only one face
178 break;
179
180 default :
181 EdgeColor = myConnCol; // edge shared by at least two faces
182 }
183
184 myEdges.Append(new DBRep_Edge (theEdge,EdgeColor));
185 }
186}
187
188
189//=======================================================================
190//function : ChangeNbIsos
191//purpose : Changes the number of isoparametric curves in a shape.
192//=======================================================================
193
194void DBRep_DrawableShape::ChangeNbIsos (const Standard_Integer NbIsos)
195{
196 myFaces.Clear();
197 myNbIsos = NbIsos ;
198 TopExp_Explorer ExpFace;
199 TopLoc_Location l;
200
201 for (ExpFace.Init (myShape, TopAbs_FACE);
202 ExpFace.More();
203 ExpFace.Next()) {
204 TopoDS_Face TopologicalFace = TopoDS::Face (ExpFace.Current());
205 const Handle(Geom_Surface)& S =
206 BRep_Tool::Surface(TopologicalFace,l);
207 if (myNbIsos != 0) {
208 if (!S.IsNull()) {
209 TopologicalFace.Orientation (TopAbs_FORWARD) ;
210 DBRep_IsoBuilder IsoBuild (TopologicalFace, mySize, myNbIsos) ;
211 myFaces.Append
212 (new DBRep_Face
213 (TopologicalFace, IsoBuild.NbDomains(), myIsosCol)) ;
214 IsoBuild.LoadIsos (myFaces.Last()) ;
215 }
216 else myFaces.Append(new DBRep_Face(TopologicalFace,0, myEdgeCol));
217 }
218 else myFaces.Append(new DBRep_Face(TopologicalFace,0, myEdgeCol));
219 }
220}
221
222//=======================================================================
223// Function : NbIsos
224// Purpose : Returns the number of isoparametric curves in a shape.
225//=======================================================================
226
227Standard_Integer DBRep_DrawableShape::NbIsos () const
228{
229 return myNbIsos ;
230}
231
232//=======================================================================
233// Function : Discret
234// Purpose :
235//=======================================================================
236
237Standard_Integer DBRep_DrawableShape::Discret () const
238{
239 return myDiscret ;
240}
241
242Standard_EXPORT Draw_Color DBRep_ColorOrientation (const TopAbs_Orientation Or);
243
244
245static void PlotIso (Draw_Display& dis,
246 Handle(DBRep_Face)& F,
247 BRepAdaptor_Surface& S,
248 GeomAbs_IsoType T,
249 Standard_Real& U,
250 Standard_Real& V,
251 Standard_Real Step,
252 Standard_Boolean& halt)
253{
254
255 ++PlotCount;
256
257 gp_Pnt Pl, Pr, Pm;
258
259 if (T == GeomAbs_IsoU) {
260 S.D0(U, V, Pl);
261 S.D0(U, V + Step/2., Pm);
262 S.D0(U, V + Step, Pr);
263 } else {
264 S.D0(U, V, Pl);
265 S.D0(U + Step/2., V, Pm);
266 S.D0(U + Step, V, Pr);
267 }
268
269 if (PlotCount > MaxPlotCount) {
270 dis.DrawTo(Pr);
271 if (dis.HasPicked()) {
272 pickshape = F->Face();
273 upick = (T == GeomAbs_IsoU) ? U : U + Step;
274 vpick = (T == GeomAbs_IsoU) ? V + Step : V;
275 halt = Standard_True;
276 };
277 return;
278 }
279
280 if (Pm.Distance(Pl) + Pm.Distance(Pr) <= IsoRatio*Pl.Distance(Pr)) {
281 dis.DrawTo(Pr);
282 if (dis.HasPicked()) {
283 pickshape = F->Face();
284 upick = (T == GeomAbs_IsoU) ? U : U + Step;
285 vpick = (T == GeomAbs_IsoU) ? V + Step : V;
286 halt = Standard_True;
287 };
288 } else
289 if (T == GeomAbs_IsoU) {
290 PlotIso (dis, F, S, T, U, V, Step/2, halt);
291 Standard_Real aLocalV = V + Step/2 ;
292 PlotIso (dis, F, S, T, U, aLocalV , Step/2, halt);
293 } else {
294 PlotIso (dis, F, S, T, U, V, Step/2, halt);
295 Standard_Real aLocalU = U + Step/2 ;
296 PlotIso (dis, F, S, T, aLocalU , V, Step/2, halt);
297 }
298}
299
300
301static void PlotEdge (Draw_Display& dis,
302 Handle(DBRep_Edge)& E,
303 const Adaptor3d_Curve& C,
304 Standard_Real& f,
305 Standard_Real step,
306 Standard_Boolean& halt)
307{
308
309 ++PlotCount;
310
311 gp_Pnt Pl, Pr, Pm;
312
313 C.D0(f, Pl);
314 C.D0(f + step/2., Pm);
315 C.D0(f + step, Pr);
316
317 if (PlotCount > MaxPlotCount) {
318 dis.DrawTo(Pr);
319 if (dis.HasPicked()) {
320 pickshape = E->Edge();
321 upick = f + step;
322 vpick = 0;
323 halt = Standard_True;
324 }
325 return;
326 }
327
328
329 if (Pm.Distance(Pl) + Pm.Distance(Pr) <= IsoRatio*Pl.Distance(Pr)) {
330 dis.DrawTo(Pr);
331 if (dis.HasPicked()) {
332 pickshape = E->Edge();
333 upick = f + step;
334 vpick = 0;
335 halt = Standard_True;
336 };
337 } else {
338 PlotEdge (dis, E, C, f, step/2, halt);
339 Standard_Real aLocalF = f + step/2 ;
340 PlotEdge (dis, E, C, aLocalF , step/2, halt);
341 }
342}
343
344//=======================================================================
345//function : DrawOn
346//purpose :
347//=======================================================================
348
349void DBRep_DrawableShape::DrawOn(Draw_Display& dis) const
350{
351 Standard_Boolean halt = Standard_False;
352
353 if (myShape.IsNull()) {
354 dis.SetColor(myConnCol);
355 dis.DrawString(gp_Pnt(0,0,0),"Null Shape");
356 return;
357 }
358
6662fe63 359 if (myFaces.IsEmpty() || myEdges.IsEmpty())
360 updateDisplayData();
361
7fd59977 362 // hidden lines
363 if (myHLR) {
364 DBRep_DrawableShape* p = (DBRep_DrawableShape*) this;
365 p->DisplayHiddenLines(dis);
366 return;
367 }
368
369 GeomAbs_IsoType T;
370 Standard_Real Par,T1,T2;
371 Standard_Real U1,U2,V1,V2,stepU=0.,stepV=0.;
372// gp_Pnt P, P1;
373 gp_Pnt P;
374 Standard_Integer i,j;
375
376 // Faces
377 Handle(Poly_Triangulation) Tr;
51740958 378 TopLoc_Location aTempLoc;
7fd59977 379 TopLoc_Location loc;
380
381 DBRep_ListIteratorOfListOfFace itf(myFaces);
382
383 while (itf.More() && !halt) {
384
385 const Handle(DBRep_Face)& F = itf.Value();
386 dis.SetColor(F->Color());
387
51740958 388 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F->Face(), aTempLoc);
7fd59977 389
51740958 390 if (!aSurf.IsNull()) {
7fd59977 391
392 Standard_Boolean restriction = Standard_False;
51740958 393 if(aSurf->IsUPeriodic() || aSurf->IsVPeriodic()) {
7fd59977 394 Standard_Real SU1 = 0., SU2 = 0., SV1 = 0., SV2 = 0.;
395 Standard_Real FU1 = 0., FU2 = 0., FV1 = 0., FV2 = 0.;
51740958 396 aSurf->Bounds(SU1,SU2,SV1,SV2);
7fd59977 397 BRepTools::UVBounds (F->Face(),FU1,FU2,FV1,FV2);
51740958 398 if(aSurf->IsUPeriodic()) {
7fd59977 399 if(FU1 < SU1 || FU1 > SU2)
400 restriction = Standard_True;
401 if(!restriction && (FU2 < SU1 || FU2 > SU2))
402 restriction = Standard_True;
403 }
51740958 404 if(!restriction && aSurf->IsVPeriodic()) {
7fd59977 405 if(FV1 < SV1 || FV1 > SV2)
406 restriction = Standard_True;
407 if(!restriction && (FV2 < SV1 || FV2 > SV2))
408 restriction = Standard_True;
409 }
410 Standard_Boolean zeroS = (fabs(SU2-SU1) <= 1.e-9 || fabs(SV2-SV1) <= 1.e-9);
411 Standard_Boolean zeroF = (fabs(FU2-FU1) <= 1.e-9 || fabs(FV2-FV1) <= 1.e-9);
412 if(restriction && (zeroS || zeroF))
413 restriction = Standard_False;
414 if(restriction && (FU1 >= FU2 || FV1 >= FV2))
415 restriction = Standard_False;
416 if(restriction && (fabs(FU2-FU1) > 4.1e+100 || fabs(FV2-FV1) > 4.1e+100))
417 restriction = Standard_False;
418 }
419
420 BRepAdaptor_Surface S(F->Face(),restriction);
421
422 //BRepAdaptor_Surface S(F->Face(),Standard_False);
423
424 GeomAbs_SurfaceType SurfType = S.GetType();
425
426// If the type of the surface is GeomAbs_SurfaceOfExtrusion or GeomAbs_SurfaceOfRevolution
0797d9d3 427#ifdef OCCT_DEBUG
7fd59977 428 GeomAbs_CurveType CurvType;
429#else
430 GeomAbs_CurveType CurvType = GeomAbs_OtherCurve;
431#endif
432
433 Standard_Integer N = F->NbIsos();
434
435 Standard_Integer Intrv, nbIntv;
436 Standard_Integer nbUIntv = S.NbUIntervals(GeomAbs_CN);
437 Standard_Integer nbVIntv = S.NbVIntervals(GeomAbs_CN);
438 TColStd_Array1OfReal TI(1,Max(nbUIntv, nbVIntv)+1);
439
440 for (i = 1; i <= N; i++) {
441
442 F->GetIso(i,T,Par,T1,T2);
443 if (T == GeomAbs_IsoU) {
444 S.VIntervals(TI, GeomAbs_CN);
445 V1 = Max(T1, TI(1));
446 V2 = Min(T2, TI(2));
447 U1 = Par;
448 U2 = Par;
449 stepU = 0;
450 nbIntv = nbVIntv;
451 }
452 else {
453 S.UIntervals(TI, GeomAbs_CN);
454 U1 = Max(T1, TI(1));
455 U2 = Min(T2, TI(2));
456 V1 = Par;
457 V2 = Par;
458 stepV = 0;
459 nbIntv = nbUIntv;
460 }
461
462 S.D0(U1,V1,P);
463 dis.MoveTo(P);
464
465 for (Intrv = 1; Intrv <= nbIntv; Intrv++) {
466
467 if (TI(Intrv) <= T1 && TI(Intrv + 1) <= T1)
468 continue;
469 if (TI(Intrv) >= T2 && TI(Intrv + 1) >= T2)
470 continue;
471 if (T == GeomAbs_IsoU) {
472 V1 = Max(T1, TI(Intrv));
473 V2 = Min(T2, TI(Intrv + 1));
474 stepV = (V2 - V1) / myDiscret;
475 }
476 else {
477 U1 = Max(T1, TI(Intrv));
478 U2 = Min(T2, TI(Intrv + 1));
479 stepU = (U2 - U1) / myDiscret;
480 }
481
482 switch (SurfType) {
483//-------------GeomAbs_Plane---------------
484 case GeomAbs_Plane :
485 break;
486//----GeomAbs_Cylinder GeomAbs_Cone------
487 case GeomAbs_Cylinder :
488 case GeomAbs_Cone :
489 if (T == GeomAbs_IsoV) {
490 for (j = 1; j < myDiscret; j++) {
491 U1 += stepU;
492 V1 += stepV;
493 S.D0(U1,V1,P);
494 dis.DrawTo(P);
495 if (dis.HasPicked()) {
496 pickshape = F->Face();
497 upick = U1;
498 vpick = V1;
499 halt = Standard_True;
500 }
501 }
502 }
503 break;
504//---GeomAbs_Sphere GeomAbs_Torus--------
505//GeomAbs_BezierSurface GeomAbs_BezierSurface
506 case GeomAbs_Sphere :
507 case GeomAbs_Torus :
508 case GeomAbs_OffsetSurface :
509 case GeomAbs_OtherSurface :
510 for (j = 1; j < myDiscret; j++) {
511 U1 += stepU;
512 V1 += stepV;
513 S.D0(U1,V1,P);
514 dis.DrawTo(P);
515 if (dis.HasPicked()) {
516 pickshape = F->Face();
517 upick = U1;
518 vpick = V1;
519 halt = Standard_True;
520 }
521 }
522 break;
523//-------------GeomAbs_BSplineSurface------
524 case GeomAbs_BezierSurface :
525 case GeomAbs_BSplineSurface :
526 for (j = 1; j <= myDiscret/2; j++) {
527 Handle(DBRep_Face) aLocalFace = F;
528
529 PlotCount = 0;
530
531 PlotIso (dis, aLocalFace , S, T, U1, V1, (T == GeomAbs_IsoV) ? stepU*2. : stepV*2., halt);
532 U1 += stepU*2.;
533 V1 += stepV*2.;
534 }
535 break;
536//-------------GeomAbs_SurfaceOfExtrusion--
537//-------------GeomAbs_SurfaceOfRevolution-
538 case GeomAbs_SurfaceOfExtrusion :
539 case GeomAbs_SurfaceOfRevolution :
540 if ((T == GeomAbs_IsoV && SurfType == GeomAbs_SurfaceOfRevolution) ||
541 (T == GeomAbs_IsoU && SurfType == GeomAbs_SurfaceOfExtrusion)) {
542 if (SurfType == GeomAbs_SurfaceOfExtrusion) break;
543 for (j = 1; j < myDiscret; j++) {
544 U1 += stepU;
545 V1 += stepV;
546 S.D0(U1,V1,P);
547 dis.DrawTo(P);
548 if (dis.HasPicked()) {
549 pickshape = F->Face();
550 upick = U1;
551 vpick = V1;
552 halt = Standard_True;
553 }
554 }
555 } else {
556 CurvType = (S.BasisCurve())->GetType();
557 switch (CurvType) {
558 case GeomAbs_Line :
559 break;
560 case GeomAbs_Circle :
561 case GeomAbs_Ellipse :
562 for (j = 1; j < myDiscret; j++) {
563 U1 += stepU;
564 V1 += stepV;
565 S.D0(U1,V1,P);
566 dis.DrawTo(P);
567 if (dis.HasPicked()) {
568 pickshape = F->Face();
569 upick = U1;
570 vpick = V1;
571 halt = Standard_True;
572 }
573 }
574 break;
575 case GeomAbs_Parabola :
576 case GeomAbs_Hyperbola :
577 case GeomAbs_BezierCurve :
578 case GeomAbs_BSplineCurve :
1aec3320 579 case GeomAbs_OffsetCurve :
7fd59977 580 case GeomAbs_OtherCurve :
581 for (j = 1; j <= myDiscret/2; j++) {
582 Handle(DBRep_Face) aLocalFace = F;
583
584 PlotCount = 0;
585
586 PlotIso (dis, aLocalFace, S, T, U1, V1,
587 (T == GeomAbs_IsoV) ? stepU*2. : stepV*2., halt);
588 U1 += stepU*2.;
589 V1 += stepV*2.;
590 }
591 break;
592 }
593 }
594 }
595 }
596 S.D0(U2,V2,P);
597 dis.DrawTo(P);
598 if (dis.HasPicked()) {
599 pickshape = F->Face();
600 upick = U2;
601 vpick = V2;
602 halt = Standard_True;
603 }
604 }
605 }
606
607 //=====================================
608 // trace des eventuelles triangulations.
609 //=====================================
610
51740958 611 if (aSurf.IsNull() || mytriangulations) {
7fd59977 612 Tr = BRep_Tool::Triangulation(F->Face(), loc);
613 if (!Tr.IsNull()) {
6662fe63 614 display(Tr, loc.Transformation(), dis);
7fd59977 615 }
616 }
617 itf.Next();
618 }
619
620
621 // Edges
622 DBRep_ListIteratorOfListOfEdge ite(myEdges);
623 while (ite.More() && !halt) {
624
625 const Handle(DBRep_Edge)& E = ite.Value();
626
627 if(myDispOr)
628 dis.SetColor(DBRep_ColorOrientation(E->Edge().Orientation()));
629 else
630 dis.SetColor(E->Color());
631
632 // display geometrical curve if exists.
633 Standard_Boolean isgeom = BRep_Tool::IsGeometric(E->Edge());
51740958 634 Standard_Real aCheckU1, aCheckU2;
7fd59977 635
636 if (isgeom) {
637 // check the range (to report bad edges)
51740958 638 BRep_Tool::Range(E->Edge(), aCheckU1, aCheckU2);
639 if (aCheckU2 < aCheckU1) {
7fd59977 640 // bad orientation
641 cout << "DBRep_DrawableShape : Bad parameters on edge."<<endl;
642 BRepTools::Dump(E->Edge(),cout);
643 ite.Next();
644 continue;
645 }
646
647 if (BRep_Tool::Degenerated(E->Edge())) {
648 ite.Next();
649 continue;
650 }
651
652 BRepAdaptor_Curve C(E->Edge());
653
654 Standard_Real f = C.FirstParameter();
655 Standard_Real l = C.LastParameter();
656 if (Precision::IsNegativeInfinite(f)) {
657 if (Precision::IsPositiveInfinite(l)) {
658 f = -mySize;
659 l = mySize;
660 }
661 else {
662 f = l - mySize;
663 }
664 }
665 else if (Precision::IsPositiveInfinite(l)) {
666 l = f + mySize;
667 }
668
669 Handle(Adaptor3d_HCurve) HC = C.Trim(f, l, Precision::Confusion());
670 GeomAbs_CurveType CurvType = HC->GetType();
671
672 Standard_Integer intrv, nbintv = HC->NbIntervals(GeomAbs_CN);
673 TColStd_Array1OfReal TI(1,nbintv+1);
674 HC->Intervals(TI,GeomAbs_CN);
675
676 HC->D0(HC->FirstParameter(), P);
677 dis.MoveTo(P);
678
679 for (intrv = 1; intrv <= nbintv; intrv++) {
680 Standard_Real t = TI(intrv);
681 Standard_Real step = (TI(intrv+1) - t) / myDiscret;
682
683 switch (CurvType) {
684 case GeomAbs_Line :
685 break;
686 case GeomAbs_Circle :
687 case GeomAbs_Ellipse :
688 for (j = 1; j < myDiscret; j++) {
689 t += step;
690 C.D0(t,P);
691 dis.DrawTo(P);
692 if (dis.HasPicked()) {
693 pickshape = E->Edge();
694 upick = t;
695 vpick = 0;
696 halt = Standard_True;
697 }
698 }
699 break;
700 case GeomAbs_Parabola :
701 case GeomAbs_Hyperbola :
702 case GeomAbs_BezierCurve :
703 case GeomAbs_BSplineCurve :
1aec3320 704 case GeomAbs_OffsetCurve :
7fd59977 705 case GeomAbs_OtherCurve :
706 for (j = 1; j <= myDiscret/2; j++) {
707 Handle(DBRep_Edge) aLocaLEdge(E);
708 PlotCount = 0;
709 PlotEdge (dis, aLocaLEdge , HC->Curve(), t, step*2., halt);
710 t += step*2.;
711 }
712 break;
713 }
714 }
715
716 C.D0(HC->LastParameter(),P);
717 dis.DrawTo(P);
718 if (dis.HasPicked()) {
719 pickshape = E->Edge();
720 upick = l;
721 vpick = 0;
722 halt = Standard_True;
723 }
724
725 if (myDispOr) {
726 // display an arrow at the end
51740958 727 gp_Pnt aPnt;
7fd59977 728 gp_Vec V;
51740958 729 C.D1(l, aPnt,V);
7fd59977 730 gp_Pnt2d p1,p2;
51740958 731 dis.Project(aPnt,p1);
732 aPnt.Translate(V);
733 dis.Project(aPnt,p2);
7fd59977 734 gp_Vec2d v(p1,p2);
735 if (v.Magnitude() > gp::Resolution()) {
736 Standard_Real L = 20 / dis.Zoom();
737 Standard_Real H = 10 / dis.Zoom();
738 gp_Dir2d d(v);
739 p2.SetCoord(p1.X() - L*d.X() - H*d.Y(), p1.Y() - L*d.Y() + H*d.X());
740 dis.MoveTo(p2);
741 p2.SetCoord(p1.X() - L*d.X() + H*d.Y(), p1.Y() - L*d.Y() - H*d.X());
742 dis.DrawTo(p1);
743 dis.DrawTo(p2);
744 }
745
746// gp_Vec tang;
747// C.D1(l,P,tang);
748
749 }
750 }
751
752 //======================================
753 // trace des representations polygonales:
754 //======================================
755
756 if (!isgeom || mypolygons) {
757
758 // Polygones 3d:
759 Handle(Poly_Polygon3D) Polyg = BRep_Tool::Polygon3D(E->Edge(), loc);
760 if (!Polyg.IsNull()) {
761 const TColgp_Array1OfPnt& Points = Polyg->Nodes();
762 Standard_Integer po;
763 for (po = Points.Lower()+1; po <= Points.Upper(); po++) {
764 dis.Draw((Points.Value(po-1)).Transformed(loc),
765 (Points.Value(po)).Transformed(loc));
766 if (dis.HasPicked()) {
767 pickshape = E->Edge();
768 upick = 0;
769 vpick = 0;
770 halt = Standard_True;
771 }
772 }
773 }
774 else {
775
776 // Polygone sur triangulation:
51740958 777 Handle(Poly_Triangulation) PolyTr;
7fd59977 778 Handle(Poly_PolygonOnTriangulation) Poly;
51740958 779 BRep_Tool::PolygonOnTriangulation(E->Edge(), Poly, PolyTr, loc);
7fd59977 780 if (!Poly.IsNull()) {
781 const TColStd_Array1OfInteger& Indices = Poly->Nodes();
51740958 782 const TColgp_Array1OfPnt& Nodes = PolyTr->Nodes();
7fd59977 783 for (i=Indices.Lower()+1; i<=Indices.Upper(); i++) {
784 dis.Draw(Nodes(Indices(i-1)).Transformed(loc),
785 Nodes(Indices(i)).Transformed(loc));
786 if (dis.HasPicked()) {
787 pickshape = E->Edge();
788 upick = 0;
789 vpick = 0;
790 halt = Standard_True;
791 }
792 }
793 }
794 }
795 }
796
797 ite.Next();
798 }
799
800
801
802
803 //Vertices
804
805 TopExp_Explorer exv;
806 dis.SetColor(myConnCol);
807
808 for (exv.Init(myShape,TopAbs_VERTEX,TopAbs_EDGE);
809 exv.More() && !halt;
810 exv.Next()){
811
812 if (myDispOr)
813 dis.SetColor(DBRep_ColorOrientation(exv.Current().Orientation()));
814 dis.DrawMarker(BRep_Tool::Pnt(TopoDS::Vertex(exv.Current())),
815 Draw_Losange);
816 if (dis.HasPicked()) {
817 pickshape = exv.Current();
818 upick = 0;
819 vpick = 0;
820 halt = Standard_True;
821 }
822
823 }
824
825}
826
827//=======================================================================
828//function : DisplayHiddenLines
829//purpose :
830//=======================================================================
831
832void DBRep_DrawableShape::DisplayHiddenLines(Draw_Display& dis)
833{
834 Standard_Integer id = dis.ViewId();
835
836 // get the projection
837 gp_Trsf T;
838 dout.GetTrsf(id,T);
839 Standard_Real focal = -1;
840 if (!strcmp(dout.GetType(id),"PERS")) focal = dout.Focal(id);
841 Standard_Real Ang,Def;
842 HLRBRep::PolyHLRAngleAndDeflection(myAng,Ang,Def);
e71669c6 843 BRepMesh_FastDiscret::Parameters aMeshParams;
844 aMeshParams.Relative = Standard_True;
845 aMeshParams.Deflection = Def;
846 aMeshParams.Angle = Ang;
847 BRepMesh_IncrementalMesh MESH(myShape, aMeshParams);
7fd59977 848 Standard_Boolean recompute = Standard_True;
849 // find if the view must be recomputed
850 DBRep_ListIteratorOfListOfHideData it(myHidData);
851
852 while (it.More()) {
853 if (it.Value().ViewId() == id) {
854 // we have the view
855 // but did we rotate it
856 Standard_Real ang = it.Value().Angle();
857 recompute = !it.Value().IsSame(T,focal) || myAng != ang;
858 if (recompute)
859 myHidData.Remove(it);
860 else {
861 it.Value().DrawOn(dis,myRg1,myRgN,myHid,
862 myConnCol,myIsosCol);
863 if (dis.HasPicked()) {
864 pickshape = it.Value().LastPick();
865 upick = 0;
866 vpick = 0;
867 }
868 }
869 break;
870 }
871 it.Next();
872 }
873 // recompute the hidden lines and display them
874 if (recompute) {
875 DBRep_HideData theData;
876 myHidData.Append(theData);
877 myHidData.Last().Set(id,T,focal,myShape,myAng);
878 myHidData.Last().DrawOn(dis,myRg1,myRgN,myHid,
879 myConnCol,myIsosCol);
880 if (dis.HasPicked()) {
881 pickshape = myHidData.Last().LastPick();
882 upick = 0;
883 vpick = 0;
884 }
885 }
886}
887
888//=======================================================================
889//function : Shape
890//purpose :
891//=======================================================================
892
893TopoDS_Shape DBRep_DrawableShape::Shape()const
894{
895 return myShape;
896}
897
898
899//=======================================================================
900//function : Copy
901//purpose :
902//=======================================================================
903
904Handle(Draw_Drawable3D) DBRep_DrawableShape::Copy()const
905{
906 Handle(DBRep_DrawableShape) D =
907 new DBRep_DrawableShape(myShape,
908 myFreeCol,
909 myConnCol,
910 myEdgeCol,
911 myIsosCol,
912 mySize,
913 myNbIsos,
914 myDiscret);
915 return D;
916}
917
918//=======================================================================
919//function : DisplayOrientation
920//purpose :
921//=======================================================================
922
923void DBRep_DrawableShape::DisplayOrientation(const Standard_Boolean D)
924{
925 myDispOr = D;
926}
927
928//=======================================================================
929//function : DisplayTriangulation
930//purpose :
931//=======================================================================
932
933void DBRep_DrawableShape::DisplayTriangulation(const Standard_Boolean D)
934{
935 mytriangulations = D;
936}
937
938//=======================================================================
939//function : DisplayPolygons
940//purpose :
941//=======================================================================
942
943void DBRep_DrawableShape::DisplayPolygons(const Standard_Boolean D)
944{
945 mypolygons = D;
946}
947
948//=======================================================================
949//function : DisplayHLR
950//purpose :
951//=======================================================================
952
953void DBRep_DrawableShape::DisplayHLR(const Standard_Boolean withHLR,
954 const Standard_Boolean withRg1,
955 const Standard_Boolean withRgN,
956 const Standard_Boolean withHid,
957 const Standard_Real ang)
958{
959 myHLR = withHLR;
960 myRg1 = withRg1;
961 myRgN = withRgN;
962 myHid = withHid;
963 myAng = ang;
964}
965
966//=======================================================================
967//function : DisplayTriangulation
968//purpose :
969//=======================================================================
970
971Standard_Boolean DBRep_DrawableShape::DisplayTriangulation() const
972{
973 return mytriangulations;
974}
975
976//=======================================================================
977//function : DisplayPolygons
978//purpose :
979//=======================================================================
980
981Standard_Boolean DBRep_DrawableShape::DisplayPolygons()const
982{
983 return mypolygons;
984}
985
986//=======================================================================
987//function : GetDisplayHLR
988//purpose :
989//=======================================================================
990
991void DBRep_DrawableShape::GetDisplayHLR(Standard_Boolean& withHLR,
992 Standard_Boolean& withRg1,
993 Standard_Boolean& withRgN,
994 Standard_Boolean& withHid,
995 Standard_Real& ang) const
996{
997 withHLR = myHLR;
998 withRg1 = myRg1;
999 withRgN = myRgN;
1000 withHid = myHid;
1001 ang = myAng;
1002}
1003
1004//=======================================================================
1005//function : Dump
1006//purpose :
1007//=======================================================================
1008
1009void DBRep_DrawableShape::Dump(Standard_OStream& S)const
1010{
1011 BRepTools::Dump(myShape,S);
1012}
1013
1014
1015//=======================================================================
1016//function : Whatis
1017//purpose :
1018//=======================================================================
1019
1020void DBRep_DrawableShape::Whatis(Draw_Interpretor& s)const
1021{
d2e60688 1022 if (myShape.IsNull())
1023 {
1024 return;
1025 }
7fd59977 1026
d2e60688 1027 s << "shape " << TopAbs::ShapeTypeToString (myShape.ShapeType())
1028 << " " << TopAbs::ShapeOrientationToString(myShape.Orientation());
7fd59977 1029
d2e60688 1030 if (myShape.Free()) s <<" Free";
1031 if (myShape.Modified()) s <<" Modified";
1032 if (myShape.Orientable()) s <<" Orientable";
1033 if (myShape.Closed()) s <<" Closed";
1034 if (myShape.Infinite()) s <<" Infinite";
1035 if (myShape.Convex()) s <<" Convex";
7fd59977 1036}
1037
7fd59977 1038//=======================================================================
1039//function : LastPick
1040//purpose :
1041//=======================================================================
1042
1043void DBRep_DrawableShape::LastPick(TopoDS_Shape& s,
1044 Standard_Real& u, Standard_Real& v)
1045{
1046 s = pickshape;
1047 u = upick;
1048 v = vpick;
1049}
1050
1051
1052
1053//=======================================================================
6662fe63 1054//function : display
7fd59977 1055//purpose :
1056//=======================================================================
1057
6662fe63 1058void DBRep_DrawableShape::display(const Handle(Poly_Triangulation)& T,
7fd59977 1059 const gp_Trsf& tr,
1060 Draw_Display& dis) const
1061{
1062 // Build the connect tool
1063 Poly_Connect pc(T);
1064
1065 Standard_Integer i,j, nFree, nbTriangles = T->NbTriangles();
1066 Standard_Integer t[3];
1067
1068 // count the free edges
1069 nFree = 0;
1070 for (i = 1; i <= nbTriangles; i++) {
1071 pc.Triangles(i,t[0],t[1],t[2]);
1072 for (j = 0; j < 3; j++)
1073 if (t[j] == 0) nFree++;
1074 }
1075
1076 // allocate the arrays
e40d1acc 1077 TColStd_Array1OfInteger Free (1, Max (1, 2 * nFree));
182bd7bc 1078 NCollection_Vector< NCollection_Vec2<Standard_Integer> > anInternal;
1079
1080 Standard_Integer fr = 1;
7fd59977 1081 const Poly_Array1OfTriangle& triangles = T->Triangles();
1082 Standard_Integer n[3];
1083 for (i = 1; i <= nbTriangles; i++) {
1084 pc.Triangles(i,t[0],t[1],t[2]);
1085 triangles(i).Get(n[0],n[1],n[2]);
1086 for (j = 0; j < 3; j++) {
1087 Standard_Integer k = (j+1) % 3;
1088 if (t[j] == 0) {
1089 Free(fr) = n[j];
1090 Free(fr+1) = n[k];
1091 fr += 2;
1092 }
1093 // internal edge if this triangle has a lower index than the adjacent
1094 else if (i < t[j]) {
182bd7bc 1095 anInternal.Append (NCollection_Vec2<Standard_Integer> (n[j], n[k]));
7fd59977 1096 }
1097 }
1098 }
1099
1100 // Display the edges
1101 const TColgp_Array1OfPnt& Nodes = T->Nodes();
1102// cout<<"nb nodes = "<<Nodes.Length()<<endl;
1103
1104 // free edges
1105 Standard_Integer nn;
1106 dis.SetColor(Draw_rouge);
1107 nn = Free.Length() / 2;
1108 for (i = 1; i <= nn; i++) {
1109 dis.Draw(Nodes(Free(2*i-1)).Transformed(tr),
1110 Nodes(Free(2*i)).Transformed(tr));
1111 }
1112
1113 // internal edges
1114
1115 dis.SetColor(Draw_bleu);
182bd7bc 1116 for (NCollection_Vector< NCollection_Vec2<Standard_Integer> >::Iterator anInterIter (anInternal); anInterIter.More(); anInterIter.Next())
1117 {
1118 const Standard_Integer n1 = anInterIter.Value()[0];
1119 const Standard_Integer n2 = anInterIter.Value()[1];
1120 dis.Draw (Nodes(n1).Transformed(tr), Nodes(n2).Transformed(tr));
7fd59977 1121 }
1122}
1123
68ef63f9 1124//=======================================================================
1125//function : addMeshNormals
1126//purpose :
1127//=======================================================================
1128Standard_Boolean DBRep_DrawableShape::addMeshNormals (NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> >& theNormals,
1129 const TopoDS_Face& theFace,
1130 const Standard_Real theLength)
1131{
1132 TopLoc_Location aLoc;
1133 const Handle(Poly_Triangulation)& aTriangulation = BRep_Tool::Triangulation (theFace, aLoc);
1134 const Standard_Boolean hasNormals = aTriangulation->HasNormals();
1135 if (aTriangulation.IsNull()
1136 || (!hasNormals && !aTriangulation->HasUVNodes()))
1137 {
1138 return Standard_False;
1139 }
1140
1141 const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes();
1142 BRepAdaptor_Surface aSurface (theFace);
1143 for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
1144 {
1145 gp_Pnt aP1 = aNodes (aNodeIter);
1146 if (!aLoc.IsIdentity())
1147 {
1148 aP1.Transform (aLoc.Transformation());
1149 }
1150
1151 gp_Vec aNormal;
1152 if (hasNormals)
1153 {
1154 aNormal = aTriangulation->Normal (aNodeIter);
1155 }
1156 else
1157 {
1158 const gp_Pnt2d& aUVNode = aTriangulation->UVNode (aNodeIter);
1159 gp_Pnt aDummyPnt;
1160 gp_Vec aV1, aV2;
1161 aSurface.D1 (aUVNode.X(), aUVNode.Y(), aDummyPnt, aV1, aV2);
1162 aNormal = aV1.Crossed (aV2);
1163 }
1164
1165 const Standard_Real aNormalLen = aNormal.Magnitude();
1166 if (aNormalLen > 1.e-10)
1167 {
1168 aNormal.Multiply (theLength / aNormalLen);
1169 }
1170 else
1171 {
1172 aNormal.SetCoord (aNormalLen / 2.0, 0.0, 0.0);
1173 std::cout << "Null normal at node X = " << aP1.X() << ", Y = " << aP1.Y() << ", Z = " << aP1.Z() << "\n";
1174 }
1175
1176 const gp_Pnt aP2 = aP1.Translated (aNormal);
1177 theNormals.Append (std::pair<gp_Pnt, gp_Pnt> (aP1, aP2));
1178 }
1179 return Standard_True;
1180}
1181
1182//=======================================================================
1183//function : addMeshNormals
1184//purpose :
1185//=======================================================================
1186void DBRep_DrawableShape::addMeshNormals (NCollection_DataMap<TopoDS_Face, NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> > > & theNormals,
1187 const TopoDS_Shape& theShape,
1188 const Standard_Real theLength)
1189{
1190 TopLoc_Location aLoc;
1191 for (TopExp_Explorer aFaceIt(theShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next())
1192 {
1193 const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Current());
1194 NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> >* aFaceNormals = theNormals.ChangeSeek(aFace);
1195 if (aFaceNormals == NULL)
1196 {
1197 aFaceNormals = theNormals.Bound(aFace, NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> >());
1198 }
1199
1200 addMeshNormals (*aFaceNormals, aFace, theLength);
1201 }
1202}
1203
1204//=======================================================================
1205//function : addSurfaceNormals
1206//purpose :
1207//=======================================================================
1208Standard_Boolean DBRep_DrawableShape::addSurfaceNormals (NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> >& theNormals,
1209 const TopoDS_Face& theFace,
1210 const Standard_Real theLength,
1211 const Standard_Integer theNbAlongU,
1212 const Standard_Integer theNbAlongV)
1213{
1214 {
1215 TopLoc_Location aLoc;
1216 const Handle(Geom_Surface)& aSurface = BRep_Tool::Surface (theFace, aLoc);
1217 if (aSurface.IsNull())
1218 {
1219 return Standard_False;
1220 }
1221 }
1222
1223 Standard_Real aUmin = 0.0, aVmin = 0.0, aUmax = 0.0, aVmax = 0.0;
1224 BRepTools::UVBounds (theFace, aUmin, aUmax, aVmin, aVmax);
1225 const Standard_Boolean isUseMidU = (theNbAlongU == 1);
1226 const Standard_Boolean isUseMidV = (theNbAlongV == 1);
1227 const Standard_Real aDU = (aUmax - aUmin) / (isUseMidU ? 2 : (theNbAlongU - 1));
1228 const Standard_Real aDV = (aVmax - aVmin) / (isUseMidV ? 2 : (theNbAlongV - 1));
1229
1230 BRepAdaptor_Surface aSurface (theFace);
1231 for (Standard_Integer aUIter = 0; aUIter < theNbAlongU; ++aUIter)
1232 {
1233 const Standard_Real aU = aUmin + (isUseMidU ? 1 : aUIter) * aDU;
1234 for (Standard_Integer aVIter = 0; aVIter < theNbAlongV; ++aVIter)
1235 {
1236 const Standard_Real aV = aVmin + (isUseMidV ? 1 : aVIter) * aDV;
1237
1238 gp_Pnt aP1;
1239 gp_Vec aV1, aV2;
1240 aSurface.D1 (aU, aV, aP1, aV1, aV2);
1241
1242 gp_Vec aVec = aV1.Crossed (aV2);
1243 Standard_Real aNormalLen = aVec.Magnitude();
1244 if (aNormalLen > 1.e-10)
1245 {
1246 aVec.Multiply (theLength / aNormalLen);
1247 }
1248 else
1249 {
1250 aVec.SetCoord (aNormalLen / 2.0, 0.0, 0.0);
1251 std::cout << "Null normal at U = " << aU << ", V = " << aV << "\n";
1252 }
1253
1254 const gp_Pnt aP2 = aP1.Translated(aVec);
1255 theNormals.Append (std::pair<gp_Pnt, gp_Pnt> (aP1, aP2));
1256 }
1257 }
1258 return Standard_True;
1259}
1260
1261//=======================================================================
1262//function : addSurfaceNormals
1263//purpose :
1264//=======================================================================
1265void DBRep_DrawableShape::addSurfaceNormals (NCollection_DataMap<TopoDS_Face, NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> > >& theNormals,
1266 const TopoDS_Shape& theShape,
1267 const Standard_Real theLength,
1268 const Standard_Integer theNbAlongU,
1269 const Standard_Integer theNbAlongV)
1270{
1271 for (TopExp_Explorer aFaceIt (theShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next())
1272 {
1273 const TopoDS_Face& aFace = TopoDS::Face (aFaceIt.Current());
1274 NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> >* aFaceNormals = theNormals.ChangeSeek (aFace);
1275 if (aFaceNormals == NULL)
1276 {
1277 aFaceNormals = theNormals.Bound (aFace, NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> >());
1278 }
1279 addSurfaceNormals (*aFaceNormals, aFace, theLength, theNbAlongU, theNbAlongV);
1280 }
1281}