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