0026106: BRepMesh - revision of data model
[occt.git] / src / DBRep / DBRep_DrawableShape.cxx
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
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>
25 #include <DBRep_Edge.hxx>
26 #include <DBRep_Face.hxx>
27 #include <DBRep_HideData.hxx>
28 #include <DBRep_IsoBuilder.hxx>
29 #include <DBRep_ListIteratorOfListOfEdge.hxx>
30 #include <DBRep_ListIteratorOfListOfFace.hxx>
31 #include <DBRep_ListIteratorOfListOfHideData.hxx>
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>
40 #include <gp_Lin2d.hxx>
41 #include <gp_Trsf.hxx>
42 #include <HLRBRep.hxx>
43 #include <Poly_Connect.hxx>
44 #include <Poly_Polygon3D.hxx>
45 #include <Poly_PolygonOnTriangulation.hxx>
46 #include <Poly_Triangulation.hxx>
47 #include <Precision.hxx>
48 #include <Standard_DomainError.hxx>
49 #include <Standard_Type.hxx>
50 #include <TColgp_HArray1OfPnt.hxx>
51 #include <TColStd_DataMapIteratorOfDataMapOfIntegerInteger.hxx>
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>
62
63 IMPLEMENT_STANDARD_RTTIEXT(DBRep_DrawableShape,Draw_Drawable3D)
64
65 static Standard_Real IsoRatio = 1.001;
66
67 static Standard_Integer MaxPlotCount = 5; // To avoid huge recursive calls in
68 static 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
72 static TopoDS_Shape  pickshape;
73 static Standard_Real upick,vpick;
74 #ifdef _WIN32
75 extern Draw_Viewer dout;
76 #endif
77
78 //=======================================================================
79 //function : DBRep_DrawableShape
80 //purpose  : constructor
81 //=======================================================================
82
83 DBRep_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 {
107   myShape = aShape;
108 }
109
110 //=======================================================================
111 //function : updateDisplayData
112 //purpose  : 
113 //=======================================================================
114
115 void DBRep_DrawableShape::updateDisplayData () const
116 {
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;
155   TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,edgemap);
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
194 void  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
227 Standard_Integer DBRep_DrawableShape::NbIsos () const
228 {
229   return myNbIsos ;
230 }
231
232 //=======================================================================
233 // Function : Discret
234 // Purpose  : 
235 //=======================================================================
236
237 Standard_Integer DBRep_DrawableShape::Discret () const
238 {
239   return myDiscret ;
240 }
241
242 Standard_EXPORT Draw_Color DBRep_ColorOrientation (const TopAbs_Orientation Or);
243
244
245 static 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
301 static 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
349 void  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
359   if (myFaces.IsEmpty() || myEdges.IsEmpty())
360     updateDisplayData();
361
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;
378   TopLoc_Location aTempLoc;
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
388     Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F->Face(), aTempLoc);
389
390     if (!aSurf.IsNull()) {
391
392       Standard_Boolean restriction = Standard_False;
393       if(aSurf->IsUPeriodic() || aSurf->IsVPeriodic()) {
394         Standard_Real SU1 = 0., SU2 = 0., SV1 = 0., SV2 = 0.;
395         Standard_Real FU1 = 0., FU2 = 0., FV1 = 0., FV2 = 0.;
396         aSurf->Bounds(SU1,SU2,SV1,SV2);
397         BRepTools::UVBounds (F->Face(),FU1,FU2,FV1,FV2);
398         if(aSurf->IsUPeriodic()) {
399           if(FU1 < SU1 || FU1 > SU2)
400             restriction = Standard_True;
401           if(!restriction && (FU2 < SU1 || FU2 > SU2))
402             restriction = Standard_True;
403         }
404         if(!restriction && aSurf->IsVPeriodic()) {
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
427 #ifdef OCCT_DEBUG
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 :
579               case GeomAbs_OffsetCurve :
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
611     if (aSurf.IsNull() || mytriangulations) {
612       Tr = BRep_Tool::Triangulation(F->Face(), loc);
613       if (!Tr.IsNull()) {
614         display(Tr, loc.Transformation(), dis);
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());
634     Standard_Real aCheckU1, aCheckU2;
635
636     if (isgeom) {
637       // check the range (to report bad edges)
638       BRep_Tool::Range(E->Edge(), aCheckU1, aCheckU2);
639       if (aCheckU2 < aCheckU1) {
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 :
704         case GeomAbs_OffsetCurve :
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
727         gp_Pnt aPnt;
728         gp_Vec V;
729         C.D1(l, aPnt,V);
730         gp_Pnt2d p1,p2;
731         dis.Project(aPnt,p1);
732   aPnt.Translate(V);
733         dis.Project(aPnt,p2);
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:
777         Handle(Poly_Triangulation) PolyTr;
778         Handle(Poly_PolygonOnTriangulation) Poly;
779         BRep_Tool::PolygonOnTriangulation(E->Edge(), Poly, PolyTr, loc);
780         if (!Poly.IsNull()) {
781           const TColStd_Array1OfInteger& Indices = Poly->Nodes();
782           const TColgp_Array1OfPnt& Nodes = PolyTr->Nodes();
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
832 void 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);
843   IMeshTools_Parameters aMeshParams;
844   aMeshParams.Relative   = Standard_True;
845   aMeshParams.Deflection = Def;
846   aMeshParams.Angle      = Ang;
847
848   BRepMesh_IncrementalMesh MESH(myShape, aMeshParams);
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
894 TopoDS_Shape  DBRep_DrawableShape::Shape()const 
895 {
896   return myShape;
897 }
898
899
900 //=======================================================================
901 //function : Copy
902 //purpose  : 
903 //=======================================================================
904
905 Handle(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
924 void DBRep_DrawableShape::DisplayOrientation(const Standard_Boolean D)
925 {
926   myDispOr = D;
927 }
928
929 //=======================================================================
930 //function : DisplayTriangulation
931 //purpose  : 
932 //=======================================================================
933
934 void DBRep_DrawableShape::DisplayTriangulation(const Standard_Boolean D)
935 {
936   mytriangulations = D;
937 }
938
939 //=======================================================================
940 //function : DisplayPolygons
941 //purpose  : 
942 //=======================================================================
943
944 void DBRep_DrawableShape::DisplayPolygons(const Standard_Boolean D)
945 {
946   mypolygons = D;
947 }
948
949 //=======================================================================
950 //function : DisplayHLR
951 //purpose  : 
952 //=======================================================================
953
954 void 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
972 Standard_Boolean DBRep_DrawableShape::DisplayTriangulation() const
973 {
974   return mytriangulations;
975 }
976
977 //=======================================================================
978 //function : DisplayPolygons
979 //purpose  : 
980 //=======================================================================
981
982 Standard_Boolean DBRep_DrawableShape::DisplayPolygons()const
983 {
984   return mypolygons;
985 }
986
987 //=======================================================================
988 //function : GetDisplayHLR
989 //purpose  : 
990 //=======================================================================
991
992 void 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
1010 void  DBRep_DrawableShape::Dump(Standard_OStream& S)const 
1011 {
1012   BRepTools::Dump(myShape,S);
1013 }
1014
1015
1016 //=======================================================================
1017 //function : Whatis
1018 //purpose  : 
1019 //=======================================================================
1020
1021 void  DBRep_DrawableShape::Whatis(Draw_Interpretor& s)const 
1022 {
1023   if (myShape.IsNull())
1024   {
1025     return;
1026   }
1027
1028   s << "shape " << TopAbs::ShapeTypeToString       (myShape.ShapeType())
1029     << " "      << TopAbs::ShapeOrientationToString(myShape.Orientation());
1030
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";
1037 }
1038
1039 //=======================================================================
1040 //function : LastPick
1041 //purpose  : 
1042 //=======================================================================
1043
1044 void  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 //=======================================================================
1055 //function : display
1056 //purpose  : 
1057 //=======================================================================
1058
1059 void  DBRep_DrawableShape::display(const Handle(Poly_Triangulation)& T,
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
1078   TColStd_Array1OfInteger Free (1, Max (1, 2 * nFree));
1079   NCollection_Vector< NCollection_Vec2<Standard_Integer> > anInternal;
1080
1081   Standard_Integer fr = 1;
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]) {
1096         anInternal.Append (NCollection_Vec2<Standard_Integer> (n[j], n[k]));
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);
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));
1122   }
1123 }
1124
1125 //=======================================================================
1126 //function : addMeshNormals
1127 //purpose  :
1128 //=======================================================================
1129 Standard_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 //=======================================================================
1187 void 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 //=======================================================================
1209 Standard_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 //=======================================================================
1266 void 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 }