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