fae127cd643e0432b4ae34a53829411ace3ab13d
[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 static Standard_Real IsoRatio = 1.001;
64
65 static Standard_Integer MaxPlotCount = 5; // To avoid huge recursive calls in
66 static Standard_Integer PlotCount = 0;    // PlotEdge and PlotIso for cases of "bad" 
67                                           // curves and surfaces
68                                           // Set PlotCount = 0 before first call of
69                                           // PlotEdge or PlotIso
70 static TopoDS_Shape  pickshape;
71 static Standard_Real upick,vpick;
72 #ifdef _WIN32
73 extern Draw_Viewer dout;
74 #endif
75
76 //=======================================================================
77 //function : DBRep_DrawableShape
78 //purpose  : constructor
79 //=======================================================================
80
81 DBRep_DrawableShape::DBRep_DrawableShape 
82   (const TopoDS_Shape& aShape,
83    const Draw_Color& FreeCol,
84    const Draw_Color& ConnCol,
85    const Draw_Color& EdgeCol,
86    const Draw_Color& IsosCol,
87    const Standard_Real size,
88    const Standard_Integer nbisos,
89    const Standard_Integer discret) :
90   mySize(size),
91   myDiscret(discret),
92   myFreeCol(FreeCol),
93   myConnCol(ConnCol),
94   myEdgeCol(EdgeCol),
95   myIsosCol(IsosCol),
96   myNbIsos(nbisos),
97   myDispOr(Standard_False),
98   mytriangulations(Standard_False),
99   mypolygons(Standard_False),
100   myHLR(Standard_False),
101   myRg1(Standard_False),
102   myRgN(Standard_False),
103   myHid(Standard_False)
104 {
105   Set(aShape);
106 }
107
108 //=======================================================================
109 //function : Set
110 //purpose  : 
111 //=======================================================================
112
113 void  DBRep_DrawableShape::Set(const TopoDS_Shape& aShape)
114 {
115   myShape = aShape;
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(aShape,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   // hidden lines
360   if (myHLR) {
361     DBRep_DrawableShape* p = (DBRep_DrawableShape*) this;
362     p->DisplayHiddenLines(dis);
363     return;
364   }
365
366   GeomAbs_IsoType T;
367   Standard_Real Par,T1,T2;
368   Standard_Real U1,U2,V1,V2,stepU=0.,stepV=0.;
369 //  gp_Pnt P, P1;
370   gp_Pnt P;
371   Standard_Integer i,j;
372
373   // Faces
374   Handle(Poly_Triangulation) Tr;
375   TopLoc_Location aTempLoc;
376   TopLoc_Location loc;
377
378   DBRep_ListIteratorOfListOfFace itf(myFaces);
379
380   while (itf.More() && !halt) {
381
382     const Handle(DBRep_Face)& F = itf.Value();
383     dis.SetColor(F->Color());
384
385     Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F->Face(), aTempLoc);
386
387     if (!aSurf.IsNull()) {
388
389       Standard_Boolean restriction = Standard_False;
390       if(aSurf->IsUPeriodic() || aSurf->IsVPeriodic()) {
391         Standard_Real SU1 = 0., SU2 = 0., SV1 = 0., SV2 = 0.;
392         Standard_Real FU1 = 0., FU2 = 0., FV1 = 0., FV2 = 0.;
393         aSurf->Bounds(SU1,SU2,SV1,SV2);
394         BRepTools::UVBounds (F->Face(),FU1,FU2,FV1,FV2);
395         if(aSurf->IsUPeriodic()) {
396           if(FU1 < SU1 || FU1 > SU2)
397             restriction = Standard_True;
398           if(!restriction && (FU2 < SU1 || FU2 > SU2))
399             restriction = Standard_True;
400         }
401         if(!restriction && aSurf->IsVPeriodic()) {
402           if(FV1 < SV1 || FV1 > SV2)
403             restriction = Standard_True;
404           if(!restriction && (FV2 < SV1 || FV2 > SV2))
405             restriction = Standard_True;
406         }
407         Standard_Boolean  zeroS = (fabs(SU2-SU1) <= 1.e-9 || fabs(SV2-SV1) <= 1.e-9);
408         Standard_Boolean  zeroF = (fabs(FU2-FU1) <= 1.e-9 || fabs(FV2-FV1) <= 1.e-9);
409         if(restriction && (zeroS || zeroF))
410           restriction = Standard_False;
411         if(restriction && (FU1 >= FU2 || FV1 >= FV2))
412           restriction = Standard_False;
413         if(restriction && (fabs(FU2-FU1) > 4.1e+100 || fabs(FV2-FV1) > 4.1e+100))
414           restriction = Standard_False;
415       }
416
417       BRepAdaptor_Surface S(F->Face(),restriction);
418
419       //BRepAdaptor_Surface S(F->Face(),Standard_False);
420       
421       GeomAbs_SurfaceType SurfType = S.GetType();
422
423 // If the type of the surface is GeomAbs_SurfaceOfExtrusion or GeomAbs_SurfaceOfRevolution
424 #ifdef OCCT_DEBUG
425       GeomAbs_CurveType CurvType;
426 #else
427       GeomAbs_CurveType CurvType = GeomAbs_OtherCurve;
428 #endif
429
430       Standard_Integer N = F->NbIsos();
431
432       Standard_Integer Intrv, nbIntv;
433       Standard_Integer nbUIntv = S.NbUIntervals(GeomAbs_CN);
434       Standard_Integer nbVIntv = S.NbVIntervals(GeomAbs_CN);
435       TColStd_Array1OfReal TI(1,Max(nbUIntv, nbVIntv)+1);
436
437       for (i = 1; i <= N; i++) {
438
439         F->GetIso(i,T,Par,T1,T2);
440         if (T == GeomAbs_IsoU) {
441           S.VIntervals(TI, GeomAbs_CN);
442           V1 = Max(T1, TI(1));
443           V2 = Min(T2, TI(2));
444           U1 = Par;
445           U2 = Par;
446           stepU = 0;
447           nbIntv = nbVIntv;
448         }
449         else {
450           S.UIntervals(TI, GeomAbs_CN);
451           U1 = Max(T1, TI(1));
452           U2 = Min(T2, TI(2));
453           V1 = Par;
454           V2 = Par;
455           stepV = 0;
456           nbIntv = nbUIntv;
457         }       
458         
459         S.D0(U1,V1,P);
460         dis.MoveTo(P);
461
462         for (Intrv = 1; Intrv <= nbIntv; Intrv++) {
463
464           if (TI(Intrv) <= T1 && TI(Intrv + 1) <= T1)
465             continue;
466           if (TI(Intrv) >= T2 && TI(Intrv + 1) >= T2)
467             continue;
468           if (T == GeomAbs_IsoU) {
469             V1 = Max(T1, TI(Intrv));
470             V2 = Min(T2, TI(Intrv + 1));
471             stepV = (V2 - V1) / myDiscret;
472           }
473           else {
474             U1 = Max(T1, TI(Intrv));
475             U2 = Min(T2, TI(Intrv + 1));
476             stepU = (U2 - U1) / myDiscret;
477           }
478
479           switch (SurfType) {
480 //-------------GeomAbs_Plane---------------
481           case GeomAbs_Plane :
482             break;
483 //----GeomAbs_Cylinder   GeomAbs_Cone------
484           case GeomAbs_Cylinder :
485           case GeomAbs_Cone :
486             if (T == GeomAbs_IsoV) {
487               for (j = 1; j < myDiscret; j++) {
488                 U1 += stepU;
489                 V1 += stepV;
490                 S.D0(U1,V1,P);
491                 dis.DrawTo(P);
492                 if (dis.HasPicked()) {
493                   pickshape = F->Face();
494                   upick = U1;
495                   vpick = V1;
496                   halt = Standard_True;
497                 }
498               }
499             }
500             break;
501 //---GeomAbs_Sphere   GeomAbs_Torus--------
502 //GeomAbs_BezierSurface GeomAbs_BezierSurface
503           case GeomAbs_Sphere :
504           case GeomAbs_Torus :
505           case GeomAbs_OffsetSurface :
506           case GeomAbs_OtherSurface :
507             for (j = 1; j < myDiscret; j++) {
508               U1 += stepU;
509               V1 += stepV;
510               S.D0(U1,V1,P);
511               dis.DrawTo(P);
512               if (dis.HasPicked()) {
513                 pickshape = F->Face();
514                 upick = U1;
515                 vpick = V1;
516                 halt = Standard_True;
517               }
518             }
519             break;
520 //-------------GeomAbs_BSplineSurface------
521           case GeomAbs_BezierSurface :
522           case GeomAbs_BSplineSurface :
523             for (j = 1; j <= myDiscret/2; j++) {
524               Handle(DBRep_Face) aLocalFace = F;
525
526               PlotCount = 0;
527
528               PlotIso (dis, aLocalFace , S, T, U1, V1, (T == GeomAbs_IsoV) ? stepU*2. : stepV*2., halt);
529               U1 += stepU*2.;
530               V1 += stepV*2.;
531             }
532             break;
533 //-------------GeomAbs_SurfaceOfExtrusion--
534 //-------------GeomAbs_SurfaceOfRevolution-
535           case GeomAbs_SurfaceOfExtrusion :
536           case GeomAbs_SurfaceOfRevolution :
537             if ((T == GeomAbs_IsoV && SurfType == GeomAbs_SurfaceOfRevolution) ||
538                 (T == GeomAbs_IsoU && SurfType == GeomAbs_SurfaceOfExtrusion)) {
539               if (SurfType == GeomAbs_SurfaceOfExtrusion) break;
540               for (j = 1; j < myDiscret; j++) {
541                 U1 += stepU;
542                 V1 += stepV;
543                 S.D0(U1,V1,P);
544                 dis.DrawTo(P);
545                 if (dis.HasPicked()) {
546                   pickshape = F->Face();
547                   upick = U1;
548                   vpick = V1;
549                   halt = Standard_True;
550                 }
551               }
552             } else {
553               CurvType = (S.BasisCurve())->GetType();
554               switch (CurvType) {
555               case GeomAbs_Line :
556                 break;
557               case GeomAbs_Circle :
558               case GeomAbs_Ellipse :
559                 for (j = 1; j < myDiscret; j++) {
560                   U1 += stepU;
561                   V1 += stepV;
562                   S.D0(U1,V1,P);
563                   dis.DrawTo(P);
564                   if (dis.HasPicked()) {
565                     pickshape = F->Face();
566                     upick = U1;
567                     vpick = V1;
568                     halt = Standard_True;
569                   }
570                 }
571                 break;
572               case GeomAbs_Parabola :
573               case GeomAbs_Hyperbola :
574               case GeomAbs_BezierCurve :
575               case GeomAbs_BSplineCurve :
576               case GeomAbs_OffsetCurve :
577               case GeomAbs_OtherCurve :
578                 for (j = 1; j <= myDiscret/2; j++) {
579                   Handle(DBRep_Face) aLocalFace = F;    
580
581                   PlotCount = 0;
582
583                   PlotIso (dis, aLocalFace, S, T, U1, V1,
584                            (T == GeomAbs_IsoV) ? stepU*2. : stepV*2., halt);
585                   U1 += stepU*2.;
586                   V1 += stepV*2.;
587                 }
588                 break;
589               }
590             }
591           }
592         }
593         S.D0(U2,V2,P);
594         dis.DrawTo(P);
595         if (dis.HasPicked()) {
596           pickshape = F->Face();
597           upick = U2;
598           vpick = V2;
599           halt = Standard_True;
600         }
601       }
602     }
603     
604     //=====================================
605     // trace des eventuelles triangulations.
606     //=====================================
607
608     if (aSurf.IsNull() || mytriangulations) {
609       Tr = BRep_Tool::Triangulation(F->Face(), loc);
610       if (!Tr.IsNull()) {
611         Display(Tr, loc.Transformation(), dis);
612       }
613     }
614     itf.Next();
615   }
616
617
618   // Edges
619   DBRep_ListIteratorOfListOfEdge ite(myEdges);
620   while (ite.More() && !halt) {
621
622     const Handle(DBRep_Edge)& E = ite.Value();
623     
624     if(myDispOr)
625       dis.SetColor(DBRep_ColorOrientation(E->Edge().Orientation()));
626     else
627       dis.SetColor(E->Color());
628
629     // display geometrical curve if exists.
630     Standard_Boolean isgeom = BRep_Tool::IsGeometric(E->Edge());
631     Standard_Real aCheckU1, aCheckU2;
632
633     if (isgeom) {
634       // check the range (to report bad edges)
635       BRep_Tool::Range(E->Edge(), aCheckU1, aCheckU2);
636       if (aCheckU2 < aCheckU1) {
637         // bad orientation
638         cout << "DBRep_DrawableShape : Bad parameters on edge."<<endl;
639         BRepTools::Dump(E->Edge(),cout);
640         ite.Next();
641         continue;
642       }
643
644       if (BRep_Tool::Degenerated(E->Edge())) {
645         ite.Next();
646         continue;
647       }
648         
649       BRepAdaptor_Curve C(E->Edge());
650       
651       Standard_Real f = C.FirstParameter();
652       Standard_Real l = C.LastParameter();
653       if (Precision::IsNegativeInfinite(f)) {
654         if (Precision::IsPositiveInfinite(l)) {
655           f = -mySize;
656           l = mySize;
657         }
658         else {
659           f = l - mySize;
660         }
661       }
662       else if (Precision::IsPositiveInfinite(l)) {
663         l = f + mySize;
664       }
665       
666       Handle(Adaptor3d_HCurve) HC = C.Trim(f, l, Precision::Confusion());
667       GeomAbs_CurveType CurvType = HC->GetType();
668
669       Standard_Integer intrv, nbintv = HC->NbIntervals(GeomAbs_CN);
670       TColStd_Array1OfReal TI(1,nbintv+1);
671       HC->Intervals(TI,GeomAbs_CN);
672
673       HC->D0(HC->FirstParameter(), P);
674       dis.MoveTo(P);
675
676       for (intrv = 1; intrv <= nbintv; intrv++) {
677         Standard_Real t = TI(intrv);
678         Standard_Real step = (TI(intrv+1) - t) / myDiscret;
679
680         switch (CurvType) {
681         case GeomAbs_Line :
682           break;
683         case GeomAbs_Circle :
684         case GeomAbs_Ellipse :
685           for (j = 1; j < myDiscret; j++) {
686             t += step;
687             C.D0(t,P);
688             dis.DrawTo(P);
689             if (dis.HasPicked()) {
690               pickshape = E->Edge();
691               upick = t;
692               vpick = 0;
693               halt = Standard_True;
694             }
695           }
696           break;
697         case GeomAbs_Parabola :
698         case GeomAbs_Hyperbola :
699         case GeomAbs_BezierCurve :
700         case GeomAbs_BSplineCurve :
701         case GeomAbs_OffsetCurve :
702         case GeomAbs_OtherCurve :
703           for (j = 1; j <= myDiscret/2; j++) {
704             Handle(DBRep_Edge) aLocaLEdge(E);
705             PlotCount = 0;
706             PlotEdge (dis, aLocaLEdge , HC->Curve(), t, step*2., halt);
707             t += step*2.;
708           }
709           break;
710         }
711       }
712
713         C.D0(HC->LastParameter(),P);
714         dis.DrawTo(P);
715         if (dis.HasPicked()) {
716           pickshape = E->Edge();
717           upick = l;
718           vpick = 0;
719           halt = Standard_True;
720         }
721       
722       if (myDispOr) {
723         // display an arrow at the end
724         gp_Pnt aPnt;
725         gp_Vec V;
726         C.D1(l, aPnt,V);
727         gp_Pnt2d p1,p2;
728         dis.Project(aPnt,p1);
729   aPnt.Translate(V);
730         dis.Project(aPnt,p2);
731         gp_Vec2d v(p1,p2);
732         if (v.Magnitude() > gp::Resolution()) {
733           Standard_Real L = 20 / dis.Zoom();
734           Standard_Real H = 10 / dis.Zoom();
735           gp_Dir2d d(v);
736           p2.SetCoord(p1.X() - L*d.X() - H*d.Y(), p1.Y() - L*d.Y() + H*d.X());
737           dis.MoveTo(p2);
738           p2.SetCoord(p1.X() - L*d.X() + H*d.Y(), p1.Y() - L*d.Y() - H*d.X());
739           dis.DrawTo(p1);
740           dis.DrawTo(p2);
741         }
742
743 //      gp_Vec tang;
744 //      C.D1(l,P,tang);
745         
746       }
747     }
748     
749     //======================================
750     // trace des representations polygonales:
751     //======================================
752
753     if (!isgeom || mypolygons) {
754       
755       // Polygones 3d:
756       Handle(Poly_Polygon3D) Polyg = BRep_Tool::Polygon3D(E->Edge(), loc);
757       if (!Polyg.IsNull()) {
758         const TColgp_Array1OfPnt& Points = Polyg->Nodes();
759         Standard_Integer po;
760         for (po = Points.Lower()+1; po <= Points.Upper(); po++) {
761           dis.Draw((Points.Value(po-1)).Transformed(loc), 
762                    (Points.Value(po)).Transformed(loc));
763           if (dis.HasPicked()) {
764             pickshape = E->Edge();
765             upick = 0;
766             vpick = 0;
767             halt = Standard_True;
768           }
769         }
770       }
771       else {
772
773         // Polygone sur triangulation:
774         Handle(Poly_Triangulation) PolyTr;
775         Handle(Poly_PolygonOnTriangulation) Poly;
776         BRep_Tool::PolygonOnTriangulation(E->Edge(), Poly, PolyTr, loc);
777         if (!Poly.IsNull()) {
778           const TColStd_Array1OfInteger& Indices = Poly->Nodes();
779           const TColgp_Array1OfPnt& Nodes = PolyTr->Nodes();
780           for (i=Indices.Lower()+1; i<=Indices.Upper(); i++) {
781             dis.Draw(Nodes(Indices(i-1)).Transformed(loc),
782                      Nodes(Indices(i)).Transformed(loc));
783             if (dis.HasPicked()) {
784               pickshape = E->Edge();
785               upick = 0;
786               vpick = 0;
787               halt = Standard_True;
788             }
789           }
790         }
791       }
792     }
793
794     ite.Next();
795   }
796     
797   
798
799
800   //Vertices
801   
802   TopExp_Explorer exv;
803   dis.SetColor(myConnCol);
804   
805   for (exv.Init(myShape,TopAbs_VERTEX,TopAbs_EDGE);
806        exv.More() && !halt;
807        exv.Next()){
808     
809     if (myDispOr) 
810       dis.SetColor(DBRep_ColorOrientation(exv.Current().Orientation()));
811     dis.DrawMarker(BRep_Tool::Pnt(TopoDS::Vertex(exv.Current())),
812                    Draw_Losange);
813     if (dis.HasPicked()) {
814       pickshape = exv.Current();
815       upick = 0;
816       vpick = 0;
817       halt = Standard_True;
818     }
819     
820   }
821   
822 }
823
824 //=======================================================================
825 //function : DisplayHiddenLines
826 //purpose  : 
827 //=======================================================================
828
829 void DBRep_DrawableShape::DisplayHiddenLines(Draw_Display& dis)
830 {
831   Standard_Integer id = dis.ViewId();  
832
833   // get the projection
834   gp_Trsf T;
835   dout.GetTrsf(id,T);
836   Standard_Real focal = -1;
837   if (!strcmp(dout.GetType(id),"PERS")) focal = dout.Focal(id);
838   Standard_Real Ang,Def;
839   HLRBRep::PolyHLRAngleAndDeflection(myAng,Ang,Def);
840   BRepMesh_IncrementalMesh MESH(myShape, Def, Standard_True, Ang);
841   Standard_Boolean recompute = Standard_True;
842   // find if the view must be recomputed
843   DBRep_ListIteratorOfListOfHideData it(myHidData);
844   
845   while (it.More()) {
846     if (it.Value().ViewId() == id) {
847       // we have the view
848       // but did we rotate it
849       Standard_Real ang = it.Value().Angle();
850       recompute = !it.Value().IsSame(T,focal) || myAng != ang;
851       if (recompute) 
852         myHidData.Remove(it);
853       else {
854         it.Value().DrawOn(dis,myRg1,myRgN,myHid,
855                           myConnCol,myIsosCol);
856         if (dis.HasPicked()) {
857           pickshape = it.Value().LastPick();
858           upick = 0;
859           vpick = 0;
860         }
861       }
862       break;
863     }
864     it.Next();
865   }
866   // recompute the hidden lines and display them
867   if (recompute) {
868     DBRep_HideData theData;
869     myHidData.Append(theData);
870     myHidData.Last().Set(id,T,focal,myShape,myAng);
871     myHidData.Last().DrawOn(dis,myRg1,myRgN,myHid,
872                             myConnCol,myIsosCol);
873     if (dis.HasPicked()) {
874       pickshape = myHidData.Last().LastPick();
875       upick = 0;
876       vpick = 0;
877     }
878   }
879 }
880
881 //=======================================================================
882 //function : Shape
883 //purpose  : 
884 //=======================================================================
885
886 TopoDS_Shape  DBRep_DrawableShape::Shape()const 
887 {
888   return myShape;
889 }
890
891
892 //=======================================================================
893 //function : Copy
894 //purpose  : 
895 //=======================================================================
896
897 Handle(Draw_Drawable3D)  DBRep_DrawableShape::Copy()const 
898 {
899   Handle(DBRep_DrawableShape) D =
900     new DBRep_DrawableShape(myShape,
901                             myFreeCol,
902                             myConnCol,
903                             myEdgeCol,
904                             myIsosCol,
905                             mySize,
906                             myNbIsos,
907                             myDiscret);
908   return D;
909 }
910
911 //=======================================================================
912 //function : DisplayOrientation
913 //purpose  : 
914 //=======================================================================
915
916 void DBRep_DrawableShape::DisplayOrientation(const Standard_Boolean D)
917 {
918   myDispOr = D;
919 }
920
921 //=======================================================================
922 //function : DisplayTriangulation
923 //purpose  : 
924 //=======================================================================
925
926 void DBRep_DrawableShape::DisplayTriangulation(const Standard_Boolean D)
927 {
928   mytriangulations = D;
929 }
930
931 //=======================================================================
932 //function : DisplayPolygons
933 //purpose  : 
934 //=======================================================================
935
936 void DBRep_DrawableShape::DisplayPolygons(const Standard_Boolean D)
937 {
938   mypolygons = D;
939 }
940
941 //=======================================================================
942 //function : DisplayHLR
943 //purpose  : 
944 //=======================================================================
945
946 void DBRep_DrawableShape::DisplayHLR(const Standard_Boolean withHLR,
947                                      const Standard_Boolean withRg1,
948                                      const Standard_Boolean withRgN,
949                                      const Standard_Boolean withHid,
950                                      const Standard_Real ang)
951 {
952   myHLR = withHLR;
953   myRg1 = withRg1;
954   myRgN = withRgN;
955   myHid = withHid;
956   myAng = ang;
957 }
958
959 //=======================================================================
960 //function : DisplayTriangulation
961 //purpose  : 
962 //=======================================================================
963
964 Standard_Boolean DBRep_DrawableShape::DisplayTriangulation() const
965 {
966   return mytriangulations;
967 }
968
969 //=======================================================================
970 //function : DisplayPolygons
971 //purpose  : 
972 //=======================================================================
973
974 Standard_Boolean DBRep_DrawableShape::DisplayPolygons()const
975 {
976   return mypolygons;
977 }
978
979 //=======================================================================
980 //function : GetDisplayHLR
981 //purpose  : 
982 //=======================================================================
983
984 void DBRep_DrawableShape::GetDisplayHLR(Standard_Boolean& withHLR,
985                                         Standard_Boolean& withRg1,
986                                         Standard_Boolean& withRgN,
987                                         Standard_Boolean& withHid,
988                                         Standard_Real& ang) const
989 {
990   withHLR = myHLR;
991   withRg1 = myRg1;
992   withRgN = myRgN;
993   withHid = myHid;
994   ang     = myAng;
995 }
996
997 //=======================================================================
998 //function : Dump
999 //purpose  : 
1000 //=======================================================================
1001
1002 void  DBRep_DrawableShape::Dump(Standard_OStream& S)const 
1003 {
1004   BRepTools::Dump(myShape,S);
1005 }
1006
1007
1008 //=======================================================================
1009 //function : Whatis
1010 //purpose  : 
1011 //=======================================================================
1012
1013 void  DBRep_DrawableShape::Whatis(Draw_Interpretor& s)const 
1014 {
1015   if (!myShape.IsNull()) {
1016       s << "shape ";
1017       switch (myShape.ShapeType()) {
1018       case TopAbs_COMPOUND :
1019         s << "COMPOUND";
1020         break;
1021       case TopAbs_COMPSOLID :
1022         s << "COMPSOLID";
1023         break;
1024       case TopAbs_SOLID :
1025         s << "SOLID";
1026         break;
1027       case TopAbs_SHELL :
1028         s << "SHELL";
1029         break;
1030       case TopAbs_FACE :
1031         s << "FACE";
1032         break;
1033       case TopAbs_WIRE :
1034         s << "WIRE";
1035         break;
1036       case TopAbs_EDGE :
1037         s << "EDGE";
1038         break;
1039       case TopAbs_VERTEX :
1040         s << "VERTEX";
1041         break;
1042       case TopAbs_SHAPE :
1043         s << "SHAPE";
1044         break;
1045       }
1046
1047       s << " ";
1048
1049       switch (myShape.Orientation()) {
1050       case TopAbs_FORWARD :
1051         s << "FORWARD";
1052         break;
1053       case TopAbs_REVERSED :
1054         s << "REVERSED";
1055         break;
1056       case TopAbs_INTERNAL :
1057         s << "INTERNAL";
1058         break;
1059       case TopAbs_EXTERNAL :
1060         s << "EXTERNAL";
1061         break;
1062       }
1063
1064       if (myShape.Free())       s <<" Free";
1065       if (myShape.Modified())   s <<" Modified";
1066       if (myShape.Orientable()) s <<" Orientable";
1067       if (myShape.Closed())     s <<" Closed";
1068       if (myShape.Infinite())   s <<" Infinite";
1069       if (myShape.Convex())     s <<" Convex";
1070     }
1071 }
1072
1073
1074 //=======================================================================
1075 //function : LastPick
1076 //purpose  : 
1077 //=======================================================================
1078
1079 void  DBRep_DrawableShape::LastPick(TopoDS_Shape& s, 
1080                                     Standard_Real& u, Standard_Real& v)
1081 {
1082   s = pickshape;
1083   u = upick;
1084   v = vpick;
1085 }
1086
1087
1088
1089 //=======================================================================
1090 //function : Display
1091 //purpose  : 
1092 //=======================================================================
1093
1094 void  DBRep_DrawableShape::Display(const Handle(Poly_Triangulation)& T,
1095                                    const gp_Trsf&                    tr,
1096                                    Draw_Display&                     dis) const
1097 {
1098     // Build the connect tool
1099   Poly_Connect pc(T);
1100
1101   Standard_Integer i,j, nFree, nbTriangles = T->NbTriangles();
1102   Standard_Integer t[3];
1103
1104   // count the free edges
1105   nFree = 0;
1106   for (i = 1; i <= nbTriangles; i++) {
1107     pc.Triangles(i,t[0],t[1],t[2]);
1108     for (j = 0; j < 3; j++)
1109       if (t[j] == 0) nFree++;
1110   }
1111
1112   // allocate the arrays
1113   TColStd_Array1OfInteger Free(1,2*nFree);
1114   
1115   // array is replaced on map because it is impossible
1116   // to calculate number of internal edges in advance
1117   // due to "internal edges"
1118   TColStd_DataMapOfIntegerInteger Internal;
1119   
1120   Standard_Integer fr = 1, in = 1;
1121   const Poly_Array1OfTriangle& triangles = T->Triangles();
1122   Standard_Integer n[3];
1123   for (i = 1; i <= nbTriangles; i++) {
1124     pc.Triangles(i,t[0],t[1],t[2]);
1125     triangles(i).Get(n[0],n[1],n[2]);
1126     for (j = 0; j < 3; j++) {
1127       Standard_Integer k = (j+1) % 3;
1128       if (t[j] == 0) {
1129         Free(fr)   = n[j];
1130         Free(fr+1) = n[k];
1131         fr += 2;
1132       }
1133       // internal edge if this triangle has a lower index than the adjacent
1134       else if (i < t[j]) {
1135         Internal.Bind(in, n[j]);
1136         Internal.Bind(in+1, n[k]);
1137         in += 2;
1138       }
1139     }
1140   }
1141
1142   // Display the edges
1143   const TColgp_Array1OfPnt& Nodes = T->Nodes();
1144 //  cout<<"nb nodes = "<<Nodes.Length()<<endl;
1145   
1146   // free edges
1147   Standard_Integer nn;
1148   dis.SetColor(Draw_rouge);
1149   nn = Free.Length() / 2;
1150   for (i = 1; i <= nn; i++) {
1151     dis.Draw(Nodes(Free(2*i-1)).Transformed(tr),
1152              Nodes(Free(2*i)).Transformed(tr));
1153   }
1154   
1155   // internal edges
1156
1157   dis.SetColor(Draw_bleu);
1158   TColStd_DataMapIteratorOfDataMapOfIntegerInteger aIt(Internal);
1159   for (; aIt.More(); aIt.Next()) {
1160     Standard_Integer n1 = aIt.Value();
1161     //alvays pair is put
1162     aIt.Next();
1163     Standard_Integer n2 = aIt.Value();
1164     dis.Draw(Nodes(n1).Transformed(tr),
1165              Nodes(n2).Transformed(tr));
1166
1167   }
1168 }
1169