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():
41 GEOM_WireframeFace::~GEOM_WireframeFace()
49 vtkPolyData* aPolyData = GetOutput();
50 aPolyData->Allocate();
51 vtkPoints* aPts = vtkPoints::New();
52 aPolyData->SetPoints(aPts);
55 TFaceSet::Iterator anIter(myFaceSet);
56 for(; anIter.More(); anIter.Next()){
57 const TopoDS_Face& aFace = anIter.Value();
58 OCC2VTK(aFace,aPolyData,aPts,NbIso,Discret);
62 void GEOM_WireframeFace::SetNbIso(const int theNb[2])
64 if ( theNb[0] == NbIso[0] && theNb[1] == NbIso[1])
73 void GEOM_WireframeFace::GetNbIso(int &theNbU,int &theNbV)
81 OCC2VTK(const TopoDS_Face& theFace,
82 vtkPolyData* thePolyData,
84 const int theNbIso[2],
87 TopoDS_Face aFace = theFace;
88 aFace.Orientation(TopAbs_FORWARD);
89 CreateIso(aFace,theNbIso,theDiscret,thePolyData,thePts);
94 CreateIso(const TopoDS_Face& theFace,
95 const int theNbIso[2],
97 vtkPolyData* thePolyData,
100 // Constants for iso building
101 static Standard_Real INTERSECTOR_CONFUSION = 1.e-10 ; // -8 ;
102 static Standard_Real INTERSECTOR_TANGENCY = 1.e-10 ; // -8 ;
104 static Standard_Real HATHCER_CONFUSION_2D = 1.e-8 ;
105 static Standard_Real HATHCER_CONFUSION_3D = 1.e-8 ;
108 aHatcher(Geom2dHatch_Intersector(INTERSECTOR_CONFUSION,
109 INTERSECTOR_TANGENCY),
110 HATHCER_CONFUSION_2D,
111 HATHCER_CONFUSION_3D,
115 Standard_Real anUMin, anUMax, aVMin, aVMax;
116 TColStd_Array1OfReal anUPrm(1, theNbIso[0]), aVPrm(1, theNbIso[1]);
117 TColStd_Array1OfInteger anUInd(1, theNbIso[0]), aVInd(1, theNbIso[1]);
122 //-----------------------------------------------------------------------
123 // If the Min Max bounds are infinite, there are bounded to Infinite
125 //-----------------------------------------------------------------------
126 BRepTools::UVBounds(theFace, anUMin, anUMax, aVMin, aVMax) ;
127 Standard_Boolean InfiniteUMin = Precision::IsNegativeInfinite (anUMin) ;
128 Standard_Boolean InfiniteUMax = Precision::IsPositiveInfinite (anUMax) ;
129 Standard_Boolean InfiniteVMin = Precision::IsNegativeInfinite (aVMin) ;
130 Standard_Boolean InfiniteVMax = Precision::IsPositiveInfinite (aVMax) ;
132 static float VTKINFINITE = 1.0E38;
133 if(InfiniteUMin && InfiniteUMax){
134 anUMin = - VTKINFINITE ;
135 anUMax = VTKINFINITE ;
136 }else if(InfiniteUMin){
137 anUMin = anUMax - VTKINFINITE ;
138 }else if(InfiniteUMax){
139 anUMax = anUMin + VTKINFINITE ;
142 if(InfiniteVMin && InfiniteVMax){
143 aVMin = - VTKINFINITE ;
144 aVMax = VTKINFINITE ;
145 }else if(InfiniteVMin){
146 aVMin = aVMax - VTKINFINITE ;
147 }else if(InfiniteVMax){
148 aVMax = aVMin + VTKINFINITE ;
151 //-----------------------------------------------------------------------
152 // Retreiving the edges and loading them into the hatcher.
153 //-----------------------------------------------------------------------
154 TopExp_Explorer ExpEdges(theFace, TopAbs_EDGE);
155 for(; ExpEdges.More(); ExpEdges.Next()){
156 const TopoDS_Edge& anEdge = TopoDS::Edge(ExpEdges.Current());
157 Standard_Real U1, U2 ;
158 const Handle(Geom2d_Curve) PCurve =
159 BRep_Tool::CurveOnSurface(anEdge, theFace, U1, U2) ;
161 if(PCurve.IsNull() || U1 == U2)
164 //-- Test if a TrimmedCurve is necessary
165 if(Abs(PCurve->FirstParameter()-U1) <= Precision::PConfusion() &&
166 Abs(PCurve->LastParameter()-U2) <= Precision::PConfusion())
168 aHatcher.AddElement(PCurve, anEdge.Orientation()) ;
170 if(!PCurve->IsPeriodic()){
171 Handle(Geom2d_TrimmedCurve) TrimPCurve =
172 Handle(Geom2d_TrimmedCurve)::DownCast(PCurve);
173 if(!TrimPCurve.IsNull()){
174 Handle_Geom2d_Curve aBasisCurve = TrimPCurve->BasisCurve();
175 if(aBasisCurve->FirstParameter()-U1 > Precision::PConfusion() ||
176 U2-aBasisCurve->LastParameter() > Precision::PConfusion())
178 aHatcher.AddElement(PCurve, anEdge.Orientation()) ;
182 if(PCurve->FirstParameter()-U1 > Precision::PConfusion()){
183 U1=PCurve->FirstParameter();
185 if(U2-PCurve->LastParameter() > Precision::PConfusion()){
186 U2=PCurve->LastParameter();
190 Handle(Geom2d_TrimmedCurve) TrimPCurve =
191 new Geom2d_TrimmedCurve(PCurve, U1, U2);
192 aHatcher.AddElement(TrimPCurve, anEdge.Orientation());
197 //-----------------------------------------------------------------------
198 // Loading and trimming the hatchings.
199 //-----------------------------------------------------------------------
200 Standard_Integer IIso;
201 Standard_Real DeltaU = Abs(anUMax - anUMin) ;
202 Standard_Real DeltaV = Abs(aVMax - aVMin) ;
203 Standard_Real confusion = Min(DeltaU, DeltaV) * HATHCER_CONFUSION_3D ;
204 aHatcher.Confusion3d (confusion) ;
206 Standard_Real StepU = DeltaU / (Standard_Real)theNbIso[0];
207 if(StepU > confusion){
208 Standard_Real UPrm = anUMin + StepU / 2.;
209 gp_Dir2d Dir(0., 1.) ;
210 for(IIso = 1 ; IIso <= theNbIso[0] ; IIso++) {
211 anUPrm(IIso) = UPrm ;
212 gp_Pnt2d Ori (UPrm, 0.) ;
213 Geom2dAdaptor_Curve HCur (new Geom2d_Line (Ori, Dir)) ;
214 anUInd(IIso) = aHatcher.AddHatching (HCur) ;
219 Standard_Real StepV = DeltaV / (Standard_Real) theNbIso[1] ;
220 if(StepV > confusion){
221 Standard_Real VPrm = aVMin + StepV / 2.;
222 gp_Dir2d Dir(1., 0.);
223 for(IIso = 1 ; IIso <= theNbIso[1] ; IIso++){
225 gp_Pnt2d Ori (0., VPrm);
226 Geom2dAdaptor_Curve HCur(new Geom2d_Line (Ori, Dir));
227 aVInd(IIso) = aHatcher.AddHatching (HCur) ;
232 //-----------------------------------------------------------------------
234 //-----------------------------------------------------------------------
237 Standard_Integer aNbDom = 0 ; // for debug purpose
238 Standard_Integer Index ;
240 for(IIso = 1 ; IIso <= theNbIso[0] ; IIso++){
241 Index = anUInd(IIso) ;
243 if(aHatcher.TrimDone(Index) && !aHatcher.TrimFailed(Index)){
244 aHatcher.ComputeDomains(Index);
245 if(aHatcher.IsDone (Index))
246 aNbDom = aHatcher.NbDomains (Index);
251 for(IIso = 1 ; IIso <= theNbIso[1] ; IIso++){
254 if(aHatcher.TrimDone (Index) && !aHatcher.TrimFailed(Index)){
255 aHatcher.ComputeDomains (Index);
256 if(aHatcher.IsDone (Index))
257 aNbDom = aHatcher.NbDomains (Index);
262 //-----------------------------------------------------------------------
263 // Push iso lines in vtk kernel
264 //-----------------------------------------------------------------------
265 for(Standard_Integer UIso = anUPrm.Lower() ; UIso <= anUPrm.Upper(); UIso++){
266 Standard_Integer UInd = anUInd.Value(UIso);
268 Standard_Real UPrm = anUPrm.Value(UIso);
269 if(aHatcher.IsDone(UInd)){
270 Standard_Integer NbDom = aHatcher.NbDomains(UInd);
271 for(Standard_Integer IDom = 1 ; IDom <= NbDom ; IDom++){
272 const HatchGen_Domain& Dom = aHatcher.Domain(UInd, IDom) ;
273 Standard_Real V1 = Dom.HasFirstPoint()? Dom.FirstPoint().Parameter(): aVMin - VTKINFINITE;
274 Standard_Real V2 = Dom.HasSecondPoint()? Dom.SecondPoint().Parameter(): aVMax + VTKINFINITE;
275 CreateIso_(theFace, GeomAbs_IsoU, UPrm, V1, V2, theDiscret, thePolyData, thePts);
281 for(Standard_Integer VIso = aVPrm.Lower() ; VIso <= aVPrm.Upper(); VIso++){
282 Standard_Integer VInd = aVInd.Value(VIso);
284 Standard_Real VPrm = aVPrm.Value(VIso);
285 if(aHatcher.IsDone (VInd)){
286 Standard_Integer NbDom = aHatcher.NbDomains(VInd);
287 for (Standard_Integer IDom = 1 ; IDom <= NbDom ; IDom++){
288 const HatchGen_Domain& Dom = aHatcher.Domain(VInd, IDom);
289 Standard_Real U1 = Dom.HasFirstPoint()? Dom.FirstPoint().Parameter(): aVMin - VTKINFINITE;
290 Standard_Real U2 = Dom.HasSecondPoint()? Dom.SecondPoint().Parameter(): aVMax + VTKINFINITE;
291 CreateIso_(theFace, GeomAbs_IsoV, VPrm, U1, U2, theDiscret, thePolyData, thePts);
302 CreateIso_(const TopoDS_Face& theFace,
303 GeomAbs_IsoType theIsoType,
307 const int theDiscret,
308 vtkPolyData* thePolyData,
311 Standard_Real U1, U2, V1, V2, stepU=0., stepV=0.;
315 TopLoc_Location aLoc;
316 const Handle(Geom_Surface)& S = BRep_Tool::Surface(theFace,aLoc);
319 BRepAdaptor_Surface S(theFace,Standard_False);
321 GeomAbs_SurfaceType SurfType = S.GetType();
323 GeomAbs_CurveType CurvType = GeomAbs_OtherCurve;
325 Standard_Integer Intrv, nbIntv;
326 Standard_Integer nbUIntv = S.NbUIntervals(GeomAbs_CN);
327 Standard_Integer nbVIntv = S.NbVIntervals(GeomAbs_CN);
328 TColStd_Array1OfReal TI(1,Max(nbUIntv, nbVIntv)+1);
330 if(theIsoType == GeomAbs_IsoU){
331 S.VIntervals(TI, GeomAbs_CN);
339 S.UIntervals(TI, GeomAbs_CN);
351 for(Intrv = 1; Intrv <= nbIntv; Intrv++){
352 if(TI(Intrv) <= T1 && TI(Intrv + 1) <= T1)
354 if(TI(Intrv) >= T2 && TI(Intrv + 1) >= T2)
356 if(theIsoType == GeomAbs_IsoU){
357 V1 = Max(T1, TI(Intrv));
358 V2 = Min(T2, TI(Intrv + 1));
359 stepV = (V2 - V1) / theDiscret;
361 U1 = Max(T1, TI(Intrv));
362 U2 = Min(T2, TI(Intrv + 1));
363 stepU = (U2 - U1) / theDiscret;
369 case GeomAbs_Cylinder :
371 if(theIsoType == GeomAbs_IsoV){
372 for(j = 1; j < theDiscret; j++){
376 DrawTo(P,thePolyData,thePts);
380 case GeomAbs_Sphere :
382 case GeomAbs_OffsetSurface :
383 case GeomAbs_OtherSurface :
384 for(j = 1; j < theDiscret; j++){
388 DrawTo(P,thePolyData,thePts);
391 case GeomAbs_BezierSurface :
392 case GeomAbs_BSplineSurface :
393 for(j = 1; j <= theDiscret/2; j++){
394 Standard_Real aStep = (theIsoType == GeomAbs_IsoV) ? stepU*2. : stepV*2.;
395 CreateIso__(S, theIsoType, U1, V1, aStep, thePolyData, thePts);
400 case GeomAbs_SurfaceOfExtrusion :
401 case GeomAbs_SurfaceOfRevolution :
402 if((theIsoType == GeomAbs_IsoV && SurfType == GeomAbs_SurfaceOfRevolution) ||
403 (theIsoType == GeomAbs_IsoU && SurfType == GeomAbs_SurfaceOfExtrusion))
405 if(SurfType == GeomAbs_SurfaceOfExtrusion)
407 for(j = 1; j < theDiscret; j++){
411 DrawTo(P,thePolyData,thePts);
414 CurvType = (S.BasisCurve())->GetType();
418 case GeomAbs_Circle :
419 case GeomAbs_Ellipse :
420 for (j = 1; j < theDiscret; j++) {
424 DrawTo(P,thePolyData,thePts);
427 case GeomAbs_Parabola :
428 case GeomAbs_Hyperbola :
429 case GeomAbs_BezierCurve :
430 case GeomAbs_BSplineCurve :
431 case GeomAbs_OtherCurve :
432 for(j = 1; j <= theDiscret/2; j++){
433 Standard_Real aStep = (theIsoType == GeomAbs_IsoV) ? stepU*2. : stepV*2.;
434 CreateIso__(S, theIsoType, U1, V1, aStep, thePolyData, thePts);
444 DrawTo(P,thePolyData,thePts);
453 CreateIso__(const BRepAdaptor_Surface& theSurface,
454 GeomAbs_IsoType theIsoType,
457 Standard_Real theStep,
458 vtkPolyData* thePolyData,
462 if (theIsoType == GeomAbs_IsoU) {
463 theSurface.D0(theU, theV, Pl);
464 theSurface.D0(theU, theV + theStep/2., Pm);
465 theSurface.D0(theU, theV + theStep, Pr);
467 theSurface.D0(theU, theV, Pl);
468 theSurface.D0(theU + theStep/2., theV, Pm);
469 theSurface.D0(theU + theStep, theV, Pr);
472 static Standard_Real ISO_RATIO = 1.001;
473 if (Pm.Distance(Pl) + Pm.Distance(Pr) <= ISO_RATIO*Pl.Distance(Pr)) {
474 DrawTo(Pr,thePolyData,thePts);
476 if (theIsoType == GeomAbs_IsoU) {
477 CreateIso__(theSurface, theIsoType, theU, theV, theStep/2, thePolyData, thePts);
478 Standard_Real aLocalV = theV + theStep/2 ;
479 CreateIso__(theSurface, theIsoType, theU, aLocalV , theStep/2, thePolyData, thePts);
481 CreateIso__(theSurface, theIsoType, theU, theV, theStep/2, thePolyData, thePts);
482 Standard_Real aLocalU = theU + theStep/2 ;
483 CreateIso__(theSurface, theIsoType, aLocalU , theV, theStep/2, thePolyData, thePts);