0026106: BRepMesh - revision of data model
[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);
7bd071ed 843 IMeshTools_Parameters aMeshParams;
844 aMeshParams.Relative = Standard_True;
e71669c6 845 aMeshParams.Deflection = Def;
7bd071ed 846 aMeshParams.Angle = Ang;
847
e71669c6 848 BRepMesh_IncrementalMesh MESH(myShape, aMeshParams);
7fd59977 849 Standard_Boolean recompute = Standard_True;
850 // find if the view must be recomputed
851 DBRep_ListIteratorOfListOfHideData it(myHidData);
852
853 while (it.More()) {
854 if (it.Value().ViewId() == id) {
855 // we have the view
856 // but did we rotate it
857 Standard_Real ang = it.Value().Angle();
858 recompute = !it.Value().IsSame(T,focal) || myAng != ang;
859 if (recompute)
860 myHidData.Remove(it);
861 else {
862 it.Value().DrawOn(dis,myRg1,myRgN,myHid,
863 myConnCol,myIsosCol);
864 if (dis.HasPicked()) {
865 pickshape = it.Value().LastPick();
866 upick = 0;
867 vpick = 0;
868 }
869 }
870 break;
871 }
872 it.Next();
873 }
874 // recompute the hidden lines and display them
875 if (recompute) {
876 DBRep_HideData theData;
877 myHidData.Append(theData);
878 myHidData.Last().Set(id,T,focal,myShape,myAng);
879 myHidData.Last().DrawOn(dis,myRg1,myRgN,myHid,
880 myConnCol,myIsosCol);
881 if (dis.HasPicked()) {
882 pickshape = myHidData.Last().LastPick();
883 upick = 0;
884 vpick = 0;
885 }
886 }
887}
888
889//=======================================================================
890//function : Shape
891//purpose :
892//=======================================================================
893
894TopoDS_Shape DBRep_DrawableShape::Shape()const
895{
896 return myShape;
897}
898
899
900//=======================================================================
901//function : Copy
902//purpose :
903//=======================================================================
904
905Handle(Draw_Drawable3D) DBRep_DrawableShape::Copy()const
906{
907 Handle(DBRep_DrawableShape) D =
908 new DBRep_DrawableShape(myShape,
909 myFreeCol,
910 myConnCol,
911 myEdgeCol,
912 myIsosCol,
913 mySize,
914 myNbIsos,
915 myDiscret);
916 return D;
917}
918
919//=======================================================================
920//function : DisplayOrientation
921//purpose :
922//=======================================================================
923
924void DBRep_DrawableShape::DisplayOrientation(const Standard_Boolean D)
925{
926 myDispOr = D;
927}
928
929//=======================================================================
930//function : DisplayTriangulation
931//purpose :
932//=======================================================================
933
934void DBRep_DrawableShape::DisplayTriangulation(const Standard_Boolean D)
935{
936 mytriangulations = D;
937}
938
939//=======================================================================
940//function : DisplayPolygons
941//purpose :
942//=======================================================================
943
944void DBRep_DrawableShape::DisplayPolygons(const Standard_Boolean D)
945{
946 mypolygons = D;
947}
948
949//=======================================================================
950//function : DisplayHLR
951//purpose :
952//=======================================================================
953
954void DBRep_DrawableShape::DisplayHLR(const Standard_Boolean withHLR,
955 const Standard_Boolean withRg1,
956 const Standard_Boolean withRgN,
957 const Standard_Boolean withHid,
958 const Standard_Real ang)
959{
960 myHLR = withHLR;
961 myRg1 = withRg1;
962 myRgN = withRgN;
963 myHid = withHid;
964 myAng = ang;
965}
966
967//=======================================================================
968//function : DisplayTriangulation
969//purpose :
970//=======================================================================
971
972Standard_Boolean DBRep_DrawableShape::DisplayTriangulation() const
973{
974 return mytriangulations;
975}
976
977//=======================================================================
978//function : DisplayPolygons
979//purpose :
980//=======================================================================
981
982Standard_Boolean DBRep_DrawableShape::DisplayPolygons()const
983{
984 return mypolygons;
985}
986
987//=======================================================================
988//function : GetDisplayHLR
989//purpose :
990//=======================================================================
991
992void DBRep_DrawableShape::GetDisplayHLR(Standard_Boolean& withHLR,
993 Standard_Boolean& withRg1,
994 Standard_Boolean& withRgN,
995 Standard_Boolean& withHid,
996 Standard_Real& ang) const
997{
998 withHLR = myHLR;
999 withRg1 = myRg1;
1000 withRgN = myRgN;
1001 withHid = myHid;
1002 ang = myAng;
1003}
1004
1005//=======================================================================
1006//function : Dump
1007//purpose :
1008//=======================================================================
1009
1010void DBRep_DrawableShape::Dump(Standard_OStream& S)const
1011{
1012 BRepTools::Dump(myShape,S);
1013}
1014
1015
1016//=======================================================================
1017//function : Whatis
1018//purpose :
1019//=======================================================================
1020
1021void DBRep_DrawableShape::Whatis(Draw_Interpretor& s)const
1022{
d2e60688 1023 if (myShape.IsNull())
1024 {
1025 return;
1026 }
7fd59977 1027
d2e60688 1028 s << "shape " << TopAbs::ShapeTypeToString (myShape.ShapeType())
1029 << " " << TopAbs::ShapeOrientationToString(myShape.Orientation());
7fd59977 1030
d2e60688 1031 if (myShape.Free()) s <<" Free";
1032 if (myShape.Modified()) s <<" Modified";
1033 if (myShape.Orientable()) s <<" Orientable";
1034 if (myShape.Closed()) s <<" Closed";
1035 if (myShape.Infinite()) s <<" Infinite";
1036 if (myShape.Convex()) s <<" Convex";
7fd59977 1037}
1038
7fd59977 1039//=======================================================================
1040//function : LastPick
1041//purpose :
1042//=======================================================================
1043
1044void DBRep_DrawableShape::LastPick(TopoDS_Shape& s,
1045 Standard_Real& u, Standard_Real& v)
1046{
1047 s = pickshape;
1048 u = upick;
1049 v = vpick;
1050}
1051
1052
1053
1054//=======================================================================
6662fe63 1055//function : display
7fd59977 1056//purpose :
1057//=======================================================================
1058
6662fe63 1059void DBRep_DrawableShape::display(const Handle(Poly_Triangulation)& T,
7fd59977 1060 const gp_Trsf& tr,
1061 Draw_Display& dis) const
1062{
1063 // Build the connect tool
1064 Poly_Connect pc(T);
1065
1066 Standard_Integer i,j, nFree, nbTriangles = T->NbTriangles();
1067 Standard_Integer t[3];
1068
1069 // count the free edges
1070 nFree = 0;
1071 for (i = 1; i <= nbTriangles; i++) {
1072 pc.Triangles(i,t[0],t[1],t[2]);
1073 for (j = 0; j < 3; j++)
1074 if (t[j] == 0) nFree++;
1075 }
1076
1077 // allocate the arrays
e40d1acc 1078 TColStd_Array1OfInteger Free (1, Max (1, 2 * nFree));
182bd7bc 1079 NCollection_Vector< NCollection_Vec2<Standard_Integer> > anInternal;
1080
1081 Standard_Integer fr = 1;
7fd59977 1082 const Poly_Array1OfTriangle& triangles = T->Triangles();
1083 Standard_Integer n[3];
1084 for (i = 1; i <= nbTriangles; i++) {
1085 pc.Triangles(i,t[0],t[1],t[2]);
1086 triangles(i).Get(n[0],n[1],n[2]);
1087 for (j = 0; j < 3; j++) {
1088 Standard_Integer k = (j+1) % 3;
1089 if (t[j] == 0) {
1090 Free(fr) = n[j];
1091 Free(fr+1) = n[k];
1092 fr += 2;
1093 }
1094 // internal edge if this triangle has a lower index than the adjacent
1095 else if (i < t[j]) {
182bd7bc 1096 anInternal.Append (NCollection_Vec2<Standard_Integer> (n[j], n[k]));
7fd59977 1097 }
1098 }
1099 }
1100
1101 // Display the edges
1102 const TColgp_Array1OfPnt& Nodes = T->Nodes();
1103// cout<<"nb nodes = "<<Nodes.Length()<<endl;
1104
1105 // free edges
1106 Standard_Integer nn;
1107 dis.SetColor(Draw_rouge);
1108 nn = Free.Length() / 2;
1109 for (i = 1; i <= nn; i++) {
1110 dis.Draw(Nodes(Free(2*i-1)).Transformed(tr),
1111 Nodes(Free(2*i)).Transformed(tr));
1112 }
1113
1114 // internal edges
1115
1116 dis.SetColor(Draw_bleu);
182bd7bc 1117 for (NCollection_Vector< NCollection_Vec2<Standard_Integer> >::Iterator anInterIter (anInternal); anInterIter.More(); anInterIter.Next())
1118 {
1119 const Standard_Integer n1 = anInterIter.Value()[0];
1120 const Standard_Integer n2 = anInterIter.Value()[1];
1121 dis.Draw (Nodes(n1).Transformed(tr), Nodes(n2).Transformed(tr));
7fd59977 1122 }
1123}
1124
68ef63f9 1125//=======================================================================
1126//function : addMeshNormals
1127//purpose :
1128//=======================================================================
1129Standard_Boolean DBRep_DrawableShape::addMeshNormals (NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> >& theNormals,
1130 const TopoDS_Face& theFace,
1131 const Standard_Real theLength)
1132{
1133 TopLoc_Location aLoc;
1134 const Handle(Poly_Triangulation)& aTriangulation = BRep_Tool::Triangulation (theFace, aLoc);
1135 const Standard_Boolean hasNormals = aTriangulation->HasNormals();
1136 if (aTriangulation.IsNull()
1137 || (!hasNormals && !aTriangulation->HasUVNodes()))
1138 {
1139 return Standard_False;
1140 }
1141
1142 const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes();
1143 BRepAdaptor_Surface aSurface (theFace);
1144 for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
1145 {
1146 gp_Pnt aP1 = aNodes (aNodeIter);
1147 if (!aLoc.IsIdentity())
1148 {
1149 aP1.Transform (aLoc.Transformation());
1150 }
1151
1152 gp_Vec aNormal;
1153 if (hasNormals)
1154 {
1155 aNormal = aTriangulation->Normal (aNodeIter);
1156 }
1157 else
1158 {
1159 const gp_Pnt2d& aUVNode = aTriangulation->UVNode (aNodeIter);
1160 gp_Pnt aDummyPnt;
1161 gp_Vec aV1, aV2;
1162 aSurface.D1 (aUVNode.X(), aUVNode.Y(), aDummyPnt, aV1, aV2);
1163 aNormal = aV1.Crossed (aV2);
1164 }
1165
1166 const Standard_Real aNormalLen = aNormal.Magnitude();
1167 if (aNormalLen > 1.e-10)
1168 {
1169 aNormal.Multiply (theLength / aNormalLen);
1170 }
1171 else
1172 {
1173 aNormal.SetCoord (aNormalLen / 2.0, 0.0, 0.0);
1174 std::cout << "Null normal at node X = " << aP1.X() << ", Y = " << aP1.Y() << ", Z = " << aP1.Z() << "\n";
1175 }
1176
1177 const gp_Pnt aP2 = aP1.Translated (aNormal);
1178 theNormals.Append (std::pair<gp_Pnt, gp_Pnt> (aP1, aP2));
1179 }
1180 return Standard_True;
1181}
1182
1183//=======================================================================
1184//function : addMeshNormals
1185//purpose :
1186//=======================================================================
1187void DBRep_DrawableShape::addMeshNormals (NCollection_DataMap<TopoDS_Face, NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> > > & theNormals,
1188 const TopoDS_Shape& theShape,
1189 const Standard_Real theLength)
1190{
1191 TopLoc_Location aLoc;
1192 for (TopExp_Explorer aFaceIt(theShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next())
1193 {
1194 const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Current());
1195 NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> >* aFaceNormals = theNormals.ChangeSeek(aFace);
1196 if (aFaceNormals == NULL)
1197 {
1198 aFaceNormals = theNormals.Bound(aFace, NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> >());
1199 }
1200
1201 addMeshNormals (*aFaceNormals, aFace, theLength);
1202 }
1203}
1204
1205//=======================================================================
1206//function : addSurfaceNormals
1207//purpose :
1208//=======================================================================
1209Standard_Boolean DBRep_DrawableShape::addSurfaceNormals (NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> >& theNormals,
1210 const TopoDS_Face& theFace,
1211 const Standard_Real theLength,
1212 const Standard_Integer theNbAlongU,
1213 const Standard_Integer theNbAlongV)
1214{
1215 {
1216 TopLoc_Location aLoc;
1217 const Handle(Geom_Surface)& aSurface = BRep_Tool::Surface (theFace, aLoc);
1218 if (aSurface.IsNull())
1219 {
1220 return Standard_False;
1221 }
1222 }
1223
1224 Standard_Real aUmin = 0.0, aVmin = 0.0, aUmax = 0.0, aVmax = 0.0;
1225 BRepTools::UVBounds (theFace, aUmin, aUmax, aVmin, aVmax);
1226 const Standard_Boolean isUseMidU = (theNbAlongU == 1);
1227 const Standard_Boolean isUseMidV = (theNbAlongV == 1);
1228 const Standard_Real aDU = (aUmax - aUmin) / (isUseMidU ? 2 : (theNbAlongU - 1));
1229 const Standard_Real aDV = (aVmax - aVmin) / (isUseMidV ? 2 : (theNbAlongV - 1));
1230
1231 BRepAdaptor_Surface aSurface (theFace);
1232 for (Standard_Integer aUIter = 0; aUIter < theNbAlongU; ++aUIter)
1233 {
1234 const Standard_Real aU = aUmin + (isUseMidU ? 1 : aUIter) * aDU;
1235 for (Standard_Integer aVIter = 0; aVIter < theNbAlongV; ++aVIter)
1236 {
1237 const Standard_Real aV = aVmin + (isUseMidV ? 1 : aVIter) * aDV;
1238
1239 gp_Pnt aP1;
1240 gp_Vec aV1, aV2;
1241 aSurface.D1 (aU, aV, aP1, aV1, aV2);
1242
1243 gp_Vec aVec = aV1.Crossed (aV2);
1244 Standard_Real aNormalLen = aVec.Magnitude();
1245 if (aNormalLen > 1.e-10)
1246 {
1247 aVec.Multiply (theLength / aNormalLen);
1248 }
1249 else
1250 {
1251 aVec.SetCoord (aNormalLen / 2.0, 0.0, 0.0);
1252 std::cout << "Null normal at U = " << aU << ", V = " << aV << "\n";
1253 }
1254
1255 const gp_Pnt aP2 = aP1.Translated(aVec);
1256 theNormals.Append (std::pair<gp_Pnt, gp_Pnt> (aP1, aP2));
1257 }
1258 }
1259 return Standard_True;
1260}
1261
1262//=======================================================================
1263//function : addSurfaceNormals
1264//purpose :
1265//=======================================================================
1266void DBRep_DrawableShape::addSurfaceNormals (NCollection_DataMap<TopoDS_Face, NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> > >& theNormals,
1267 const TopoDS_Shape& theShape,
1268 const Standard_Real theLength,
1269 const Standard_Integer theNbAlongU,
1270 const Standard_Integer theNbAlongV)
1271{
1272 for (TopExp_Explorer aFaceIt (theShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next())
1273 {
1274 const TopoDS_Face& aFace = TopoDS::Face (aFaceIt.Current());
1275 NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> >* aFaceNormals = theNormals.ChangeSeek (aFace);
1276 if (aFaceNormals == NULL)
1277 {
1278 aFaceNormals = theNormals.Bound (aFace, NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> >());
1279 }
1280 addSurfaceNormals (*aFaceNormals, aFace, theLength, theNbAlongU, theNbAlongV);
1281 }
1282}