b311480e |
1 | // Created on: 1991-07-04 |
2 | // Created by: Christophe MARION |
3 | // Copyright (c) 1991-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
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 |
0797d9d3 |
431 | #ifdef OCCT_DEBUG |
7fd59977 |
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); |
14434f3e |
845 | BRepMesh_IncrementalMesh MESH(myShape, Def, Standard_True, Ang); |
7fd59977 |
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 | |