1 #include "GEOM_WireframeFace.h"
3 #include <vtkObjectFactory.h>
6 #include <vtkCellArray.h>
8 #include <vtkPolyDataMapper.h>
9 #include <vtkPolyData.h>
11 #include <Precision.hxx>
12 #include <BRepTools.hxx>
13 #include <TopExp_Explorer.hxx>
14 #include <Geom2dHatch_Hatcher.hxx>
15 #include <Geom2dHatch_Intersector.hxx>
16 #include <TColStd_Array1OfReal.hxx>
17 #include <TColStd_Array1OfInteger.hxx>
20 #include <TopoDS_Edge.hxx>
21 #include <BRep_Tool.hxx>
22 #include <Geom2d_TrimmedCurve.hxx>
23 #include <Geom2d_Line.hxx>
24 #include <gp_Dir2d.hxx>
25 #include <gp_Pnt2d.hxx>
27 #include <Geom2dHatch_Hatcher.hxx>
28 #include <HatchGen_Domain.hxx>
30 #include <Adaptor3d_HCurve.hxx>
32 vtkStandardNewMacro(GEOM_WireframeFace);
34 GEOM_WireframeFace::GEOM_WireframeFace():
40 GEOM_WireframeFace::~GEOM_WireframeFace()
48 vtkPolyData* aPolyData = GetOutput();
49 aPolyData->Allocate();
50 vtkPoints* aPts = vtkPoints::New();
51 aPolyData->SetPoints(aPts);
54 TFaceSet::Iterator anIter(myFaceSet);
55 for(; anIter.More(); anIter.Next()){
56 const TopoDS_Face& aFace = anIter.Value();
57 OCC2VTK(aFace,aPolyData,aPts,NbIso,Discret);
63 OCC2VTK(const TopoDS_Face& theFace,
64 vtkPolyData* thePolyData,
69 TopoDS_Face aFace = theFace;
70 aFace.Orientation(TopAbs_FORWARD);
71 CreateIso(aFace,theNbIso,theDiscret,thePolyData,thePts);
76 CreateIso(const TopoDS_Face& theFace,
79 vtkPolyData* thePolyData,
82 // Constants for iso building
83 static Standard_Real INTERSECTOR_CONFUSION = 1.e-10 ; // -8 ;
84 static Standard_Real INTERSECTOR_TANGENCY = 1.e-10 ; // -8 ;
86 static Standard_Real HATHCER_CONFUSION_2D = 1.e-8 ;
87 static Standard_Real HATHCER_CONFUSION_3D = 1.e-8 ;
90 aHatcher(Geom2dHatch_Intersector(INTERSECTOR_CONFUSION,
91 INTERSECTOR_TANGENCY),
97 Standard_Real anUMin, anUMax, aVMin, aVMax;
98 TColStd_Array1OfReal anUPrm(1, theNbIso), aVPrm(1, theNbIso);
99 TColStd_Array1OfInteger anUInd(1, theNbIso), aVInd(1, theNbIso);
104 //-----------------------------------------------------------------------
105 // If the Min Max bounds are infinite, there are bounded to Infinite
107 //-----------------------------------------------------------------------
108 BRepTools::UVBounds(theFace, anUMin, anUMax, aVMin, aVMax) ;
109 Standard_Boolean InfiniteUMin = Precision::IsNegativeInfinite (anUMin) ;
110 Standard_Boolean InfiniteUMax = Precision::IsPositiveInfinite (anUMax) ;
111 Standard_Boolean InfiniteVMin = Precision::IsNegativeInfinite (aVMin) ;
112 Standard_Boolean InfiniteVMax = Precision::IsPositiveInfinite (aVMax) ;
114 static float VTKINFINITE = 1.0E38;
115 if(InfiniteUMin && InfiniteUMax){
116 anUMin = - VTKINFINITE ;
117 anUMax = VTKINFINITE ;
118 }else if(InfiniteUMin){
119 anUMin = anUMax - VTKINFINITE ;
120 }else if(InfiniteUMax){
121 anUMax = anUMin + VTKINFINITE ;
124 if(InfiniteVMin && InfiniteVMax){
125 aVMin = - VTKINFINITE ;
126 aVMax = VTKINFINITE ;
127 }else if(InfiniteVMin){
128 aVMin = aVMax - VTKINFINITE ;
129 }else if(InfiniteVMax){
130 aVMax = aVMin + VTKINFINITE ;
133 //-----------------------------------------------------------------------
134 // Retreiving the edges and loading them into the hatcher.
135 //-----------------------------------------------------------------------
136 TopExp_Explorer ExpEdges(theFace, TopAbs_EDGE);
137 for(; ExpEdges.More(); ExpEdges.Next()){
138 const TopoDS_Edge& anEdge = TopoDS::Edge(ExpEdges.Current());
139 Standard_Real U1, U2 ;
140 const Handle(Geom2d_Curve) PCurve =
141 BRep_Tool::CurveOnSurface(anEdge, theFace, U1, U2) ;
143 if(PCurve.IsNull() || U1 == U2)
146 //-- Test if a TrimmedCurve is necessary
147 if(Abs(PCurve->FirstParameter()-U1) <= Precision::PConfusion() &&
148 Abs(PCurve->LastParameter()-U2) <= Precision::PConfusion())
150 aHatcher.AddElement(PCurve, anEdge.Orientation()) ;
152 if(!PCurve->IsPeriodic()){
153 Handle(Geom2d_TrimmedCurve) TrimPCurve =
154 Handle(Geom2d_TrimmedCurve)::DownCast(PCurve);
155 if(!TrimPCurve.IsNull()){
156 Handle_Geom2d_Curve aBasisCurve = TrimPCurve->BasisCurve();
157 if(aBasisCurve->FirstParameter()-U1 > Precision::PConfusion() ||
158 U2-aBasisCurve->LastParameter() > Precision::PConfusion())
160 aHatcher.AddElement(PCurve, anEdge.Orientation()) ;
164 if(PCurve->FirstParameter()-U1 > Precision::PConfusion()){
165 U1=PCurve->FirstParameter();
167 if(U2-PCurve->LastParameter() > Precision::PConfusion()){
168 U2=PCurve->LastParameter();
172 Handle(Geom2d_TrimmedCurve) TrimPCurve =
173 new Geom2d_TrimmedCurve(PCurve, U1, U2);
174 aHatcher.AddElement(TrimPCurve, anEdge.Orientation());
179 //-----------------------------------------------------------------------
180 // Loading and trimming the hatchings.
181 //-----------------------------------------------------------------------
182 Standard_Integer IIso;
183 Standard_Real DeltaU = Abs(anUMax - anUMin) ;
184 Standard_Real DeltaV = Abs(aVMax - aVMin) ;
185 Standard_Real confusion = Min(DeltaU, DeltaV) * HATHCER_CONFUSION_3D ;
186 aHatcher.Confusion3d (confusion) ;
188 Standard_Real StepU = DeltaU / (Standard_Real)theNbIso;
189 if(StepU > confusion){
190 Standard_Real UPrm = anUMin + StepU / 2.;
191 gp_Dir2d Dir(0., 1.) ;
192 for(IIso = 1 ; IIso <= theNbIso ; IIso++) {
193 anUPrm(IIso) = UPrm ;
194 gp_Pnt2d Ori (UPrm, 0.) ;
195 Geom2dAdaptor_Curve HCur (new Geom2d_Line (Ori, Dir)) ;
196 anUInd(IIso) = aHatcher.AddHatching (HCur) ;
201 Standard_Real StepV = DeltaV / (Standard_Real) theNbIso ;
202 if(StepV > confusion){
203 Standard_Real VPrm = aVMin + StepV / 2.;
204 gp_Dir2d Dir(1., 0.);
205 for(IIso = 1 ; IIso <= theNbIso ; IIso++){
207 gp_Pnt2d Ori (0., VPrm);
208 Geom2dAdaptor_Curve HCur(new Geom2d_Line (Ori, Dir));
209 aVInd(IIso) = aHatcher.AddHatching (HCur) ;
214 //-----------------------------------------------------------------------
216 //-----------------------------------------------------------------------
219 Standard_Integer aNbDom = 0 ; // for debug purpose
220 for(IIso = 1 ; IIso <= theNbIso ; IIso++){
221 Standard_Integer Index ;
223 Index = anUInd(IIso) ;
225 if(aHatcher.TrimDone(Index) && !aHatcher.TrimFailed(Index)){
226 aHatcher.ComputeDomains(Index);
227 if(aHatcher.IsDone (Index))
228 aNbDom = aHatcher.NbDomains (Index);
234 if(aHatcher.TrimDone (Index) && !aHatcher.TrimFailed(Index)){
235 aHatcher.ComputeDomains (Index);
236 if(aHatcher.IsDone (Index))
237 aNbDom = aHatcher.NbDomains (Index);
242 //-----------------------------------------------------------------------
243 // Push iso lines in vtk kernel
244 //-----------------------------------------------------------------------
245 for(Standard_Integer UIso = anUPrm.Lower() ; UIso <= anUPrm.Upper(); UIso++){
246 Standard_Integer UInd = anUInd.Value(UIso);
248 Standard_Real UPrm = anUPrm.Value(UIso);
249 if(aHatcher.IsDone(UInd)){
250 Standard_Integer NbDom = aHatcher.NbDomains(UInd);
251 for(Standard_Integer IDom = 1 ; IDom <= NbDom ; IDom++){
252 const HatchGen_Domain& Dom = aHatcher.Domain(UInd, IDom) ;
253 Standard_Real V1 = Dom.HasFirstPoint()? Dom.FirstPoint().Parameter(): aVMin - VTKINFINITE;
254 Standard_Real V2 = Dom.HasSecondPoint()? Dom.SecondPoint().Parameter(): aVMax + VTKINFINITE;
255 CreateIso_(theFace, GeomAbs_IsoU, UPrm, V1, V2, theDiscret, thePolyData, thePts);
261 for(Standard_Integer VIso = aVPrm.Lower() ; VIso <= aVPrm.Upper(); VIso++){
262 Standard_Integer VInd = aVInd.Value(VIso);
264 Standard_Real VPrm = aVPrm.Value(VIso);
265 if(aHatcher.IsDone (VInd)){
266 Standard_Integer NbDom = aHatcher.NbDomains(VInd);
267 for (Standard_Integer IDom = 1 ; IDom <= NbDom ; IDom++){
268 const HatchGen_Domain& Dom = aHatcher.Domain(VInd, IDom);
269 Standard_Real U1 = Dom.HasFirstPoint()? Dom.FirstPoint().Parameter(): aVMin - VTKINFINITE;
270 Standard_Real U2 = Dom.HasSecondPoint()? Dom.SecondPoint().Parameter(): aVMax + VTKINFINITE;
271 CreateIso_(theFace, GeomAbs_IsoV, VPrm, U1, U2, theDiscret, thePolyData, thePts);
282 CreateIso_(const TopoDS_Face& theFace,
283 GeomAbs_IsoType theIsoType,
287 const int theDiscret,
288 vtkPolyData* thePolyData,
291 Standard_Real U1, U2, V1, V2, stepU=0., stepV=0.;
295 TopLoc_Location aLoc;
296 const Handle(Geom_Surface)& S = BRep_Tool::Surface(theFace,aLoc);
299 BRepAdaptor_Surface S(theFace,Standard_False);
301 GeomAbs_SurfaceType SurfType = S.GetType();
303 GeomAbs_CurveType CurvType = GeomAbs_OtherCurve;
305 Standard_Integer Intrv, nbIntv;
306 Standard_Integer nbUIntv = S.NbUIntervals(GeomAbs_CN);
307 Standard_Integer nbVIntv = S.NbVIntervals(GeomAbs_CN);
308 TColStd_Array1OfReal TI(1,Max(nbUIntv, nbVIntv)+1);
310 if(theIsoType == GeomAbs_IsoU){
311 S.VIntervals(TI, GeomAbs_CN);
319 S.UIntervals(TI, GeomAbs_CN);
331 for(Intrv = 1; Intrv <= nbIntv; Intrv++){
332 if(TI(Intrv) <= T1 && TI(Intrv + 1) <= T1)
334 if(TI(Intrv) >= T2 && TI(Intrv + 1) >= T2)
336 if(theIsoType == GeomAbs_IsoU){
337 V1 = Max(T1, TI(Intrv));
338 V2 = Min(T2, TI(Intrv + 1));
339 stepV = (V2 - V1) / theDiscret;
341 U1 = Max(T1, TI(Intrv));
342 U2 = Min(T2, TI(Intrv + 1));
343 stepU = (U2 - U1) / theDiscret;
349 case GeomAbs_Cylinder :
351 if(theIsoType == GeomAbs_IsoV){
352 for(j = 1; j < theDiscret; j++){
356 DrawTo(P,thePolyData,thePts);
360 case GeomAbs_Sphere :
362 case GeomAbs_OffsetSurface :
363 case GeomAbs_OtherSurface :
364 for(j = 1; j < theDiscret; j++){
368 DrawTo(P,thePolyData,thePts);
371 case GeomAbs_BezierSurface :
372 case GeomAbs_BSplineSurface :
373 for(j = 1; j <= theDiscret/2; j++){
374 Standard_Real aStep = (theIsoType == GeomAbs_IsoV) ? stepU*2. : stepV*2.;
375 CreateIso__(S, theIsoType, U1, V1, aStep, thePolyData, thePts);
380 case GeomAbs_SurfaceOfExtrusion :
381 case GeomAbs_SurfaceOfRevolution :
382 if((theIsoType == GeomAbs_IsoV && SurfType == GeomAbs_SurfaceOfRevolution) ||
383 (theIsoType == GeomAbs_IsoU && SurfType == GeomAbs_SurfaceOfExtrusion))
385 if(SurfType == GeomAbs_SurfaceOfExtrusion)
387 for(j = 1; j < theDiscret; j++){
391 DrawTo(P,thePolyData,thePts);
394 CurvType = (S.BasisCurve())->GetType();
398 case GeomAbs_Circle :
399 case GeomAbs_Ellipse :
400 for (j = 1; j < theDiscret; j++) {
404 DrawTo(P,thePolyData,thePts);
407 case GeomAbs_Parabola :
408 case GeomAbs_Hyperbola :
409 case GeomAbs_BezierCurve :
410 case GeomAbs_BSplineCurve :
411 case GeomAbs_OtherCurve :
412 for(j = 1; j <= theDiscret/2; j++){
413 Standard_Real aStep = (theIsoType == GeomAbs_IsoV) ? stepU*2. : stepV*2.;
414 CreateIso__(S, theIsoType, U1, V1, aStep, thePolyData, thePts);
424 DrawTo(P,thePolyData,thePts);
433 CreateIso__(const BRepAdaptor_Surface& theSurface,
434 GeomAbs_IsoType theIsoType,
437 Standard_Real theStep,
438 vtkPolyData* thePolyData,
442 if (theIsoType == GeomAbs_IsoU) {
443 theSurface.D0(theU, theV, Pl);
444 theSurface.D0(theU, theV + theStep/2., Pm);
445 theSurface.D0(theU, theV + theStep, Pr);
447 theSurface.D0(theU, theV, Pl);
448 theSurface.D0(theU + theStep/2., theV, Pm);
449 theSurface.D0(theU + theStep, theV, Pr);
452 static Standard_Real ISO_RATIO = 1.001;
453 if (Pm.Distance(Pl) + Pm.Distance(Pr) <= ISO_RATIO*Pl.Distance(Pr)) {
454 DrawTo(Pr,thePolyData,thePts);
456 if (theIsoType == GeomAbs_IsoU) {
457 CreateIso__(theSurface, theIsoType, theU, theV, theStep/2, thePolyData, thePts);
458 Standard_Real aLocalV = theV + theStep/2 ;
459 CreateIso__(theSurface, theIsoType, theU, aLocalV , theStep/2, thePolyData, thePts);
461 CreateIso__(theSurface, theIsoType, theU, theV, theStep/2, thePolyData, thePts);
462 Standard_Real aLocalU = theU + theStep/2 ;
463 CreateIso__(theSurface, theIsoType, aLocalU , theV, theStep/2, thePolyData, thePts);