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