Salome HOME
f9198eaed372c25b6adcea42ebce3e9296bae582
[modules/geom.git] / src / OBJECT / GEOM_OCCReader.cxx
1 // Copyright (C) 2007-2023  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  GEOM OBJECT : interactive object for Geometry entities visualization
24 //  File   : GEOM_OCCReader.h
25 //  Author : Christophe ATTANASIO
26 //  Module : GEOM
27
28 #include "GEOM_OCCReader.h"
29
30 #include <GEOMUtils_Hatcher.hxx>
31
32 #include <Basics_OCCTVersion.hxx>
33
34 // VTK Includes
35 #include <vtkPoints.h>
36 #include <vtkCellArray.h>
37
38 #include <vtkObjectFactory.h>
39 #include <vtkPolyData.h>
40 #include <vtkInformation.h>
41 #include <vtkInformationVector.h>
42
43 // OpenCASCADE Includes
44 #if OCC_VERSION_LARGE < 0x07070000
45 #include <Adaptor3d_HCurve.hxx>
46 #else
47 #include <Adaptor3d_Curve.hxx>
48 #endif
49 #include <Poly_Triangulation.hxx>
50 #include <Poly_Polygon3D.hxx>
51 #include <Poly_PolygonOnTriangulation.hxx>
52 #include <TopoDS.hxx>
53 #include <TopoDS_Face.hxx>
54 #include <TopoDS_Edge.hxx>
55 #include <Precision.hxx>
56 #include <BRep_Tool.hxx>
57 #include <TColStd_Array1OfInteger.hxx>
58 #include <TColStd_Array1OfReal.hxx>
59
60 #include "utilities.h"
61
62
63 static Standard_Integer lastVTKpoint = 0;
64 static Standard_Integer PlotCount = 0;
65 static Standard_Real IsoRatio = 1.001;
66 static Standard_Integer MaxPlotCount = 5; 
67
68 //=======================================================================
69 // Function : New
70 // Purpose  : 
71 //=======================================================================
72
73 GEOM_OCCReader* GEOM_OCCReader::New()
74 {
75   vtkObject* ret = vtkObjectFactory::CreateInstance("GEOM_OCCReader");
76   if(ret) {
77     return (GEOM_OCCReader*)ret;
78   }
79   return new GEOM_OCCReader;
80 }
81
82 //=======================================================================
83 // Function : GEOM_OCCReader
84 // Purpose  : 
85 //=======================================================================
86
87 GEOM_OCCReader::GEOM_OCCReader()
88 {
89   //this->myShape = NULL;
90   this->amode = 0;
91   this->forced = Standard_False;
92   this->discretiso = 15;
93   this->nbisos = 1;
94 }
95 //=======================================================================
96 // Function : ~GEOM_OCCReader
97 // Purpose  : 
98 //=======================================================================
99
100 GEOM_OCCReader::~GEOM_OCCReader()
101 {
102 }
103
104
105 //=======================================================================
106 // Function : RequestData
107 // Purpose  : 
108 //=======================================================================
109
110 int GEOM_OCCReader::RequestData(vtkInformation *vtkNotUsed(request),
111                                 vtkInformationVector **/*inputVector*/,
112                                 vtkInformationVector *outputVector)
113 {
114   vtkInformation *outInfo = outputVector->GetInformationObject(0);
115   vtkPolyData *output = vtkPolyData::SafeDownCast(
116     outInfo->Get(vtkDataObject::DATA_OBJECT()));
117
118   vtkPoints* Pts = NULL;
119   vtkCellArray* Cells = NULL;
120   TopLoc_Location aLoc;
121
122   // Allocation
123   Pts = vtkPoints::New();
124   Cells = vtkCellArray::New();
125         
126   //Compute number of triangles and points
127   Standard_Integer nbpoly=0,nbpts=0;
128
129   if(amode==1) {
130     //for shading
131     
132     if(myShape.ShapeType() == TopAbs_FACE) {
133       // whole FACE 
134       const TopoDS_Face& aFace = TopoDS::Face(myShape);
135       Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc);
136       if(aPoly.IsNull()) {
137         Pts->Delete();
138         Cells->Delete();
139         return 0;
140       }
141
142       nbpts = aPoly->NbNodes();
143       nbpoly = aPoly->NbTriangles();
144
145       Pts->SetNumberOfPoints(nbpts);
146       Cells->Allocate(Cells->EstimateSize(nbpoly,3));
147     }
148     else { 
149         Cells->Delete();
150         Pts->Delete();
151         return 0; 
152     }
153   }
154
155   // Start computation
156   if(amode == 0) {
157     ComputeWireframe(Pts,Cells);
158     output->SetPoints(Pts);
159     output->SetLines(Cells);
160     output->Squeeze();
161   }
162   else {
163     if(myShape.ShapeType() == TopAbs_FACE) {
164       ComputeShading(Pts,Cells);
165
166       output->SetPoints(Pts);
167       output->SetPolys(Cells);
168       output->Squeeze();
169     }
170   }
171   Pts->Delete();
172   Cells->Delete();
173   return 1;
174 }
175
176 //=======================================================================
177 // Function : ComputeWireframe
178 // Purpose  : Compute the shape in CAD wireframe mode
179 //=======================================================================
180
181 void GEOM_OCCReader::ComputeWireframe(vtkPoints* Pts,vtkCellArray* Cells){
182
183   // Check the type of the shape:
184   if(myShape.ShapeType() == TopAbs_FACE) {
185     // Face
186     TransferFaceWData(TopoDS::Face(myShape),Pts,Cells);
187   } else if(myShape.ShapeType() == TopAbs_EDGE) {
188     // Edge
189     TransferEdgeWData(TopoDS::Edge(myShape),Pts,Cells);
190   } else {
191     if(myShape.ShapeType() == TopAbs_VERTEX) {
192       // Vertex
193       TransferVertexWData(TopoDS::Vertex(myShape),Pts,Cells);
194     }
195   }
196 }
197
198 //=======================================================================
199 // Function : TransferFaceWData
200 // Purpose  : Transfer wireframe data for FACE
201 //=======================================================================
202
203 void GEOM_OCCReader::TransferFaceWData(const TopoDS_Face& aFace,
204                                          vtkPoints* Pts,
205                                          vtkCellArray* Cells) 
206 {
207   TopoDS_Face aCopyFace = aFace; 
208   aCopyFace.Orientation (TopAbs_FORWARD);
209   createISO(aCopyFace,1,Pts,Cells);
210 }
211
212 //=======================================================================
213 // Function : createISO
214 // Purpose  : Create ISO for Face Wireframe representation 
215 //=======================================================================
216
217 void GEOM_OCCReader::createISO (const TopoDS_Face      &TopologicalFace,
218                                 const Standard_Integer  NbIsos,
219                                       vtkPoints        *Pts,
220                                       vtkCellArray     *Cell)
221 {
222   GEOMUtils::Hatcher aHatcher(TopologicalFace);
223
224   aHatcher.Init(NbIsos);
225   aHatcher.Perform();
226
227   if (aHatcher.IsDone()) {
228     // Push iso lines in vtk kernel
229     Standard_Integer  pt_start_idx = 0;
230
231     createIsos(aHatcher, Standard_True, pt_start_idx, Pts, Cell);
232     createIsos(aHatcher, Standard_False, pt_start_idx, Pts, Cell);
233   }
234 }
235
236 //=======================================================================
237 // Function : createIsos
238 // Purpose  : Create isolines obtained from hatcher.
239 //=======================================================================
240 void GEOM_OCCReader::createIsos(const GEOMUtils::Hatcher &theHatcher,
241                                 const Standard_Boolean   IsUIso,
242                                       Standard_Integer  &pt_start_idx,
243                                       vtkPoints         *Pts,
244                                       vtkCellArray      *Cell)
245 {
246   // Push iso lines in vtk kernel
247   Handle(TColStd_HArray1OfInteger) anIndices;
248   Handle(TColStd_HArray1OfReal)    aParams;
249
250   if (IsUIso) {
251     // U-isolines
252     anIndices = theHatcher.GetUIndices();
253     aParams   = theHatcher.GetUParams();
254   } else {
255     // V-isolines
256     anIndices = theHatcher.GetVIndices();
257     aParams   = theHatcher.GetVParams();
258   }
259
260   if (anIndices.IsNull() || aParams.IsNull()) {
261     if (IsUIso) {
262       MESSAGE("GEOMUtils_Hatcher: null U-isoline indices");
263     } else {
264       MESSAGE("GEOMUtils_Hatcher: null V-isoline indices");
265     }
266   } else {
267     const GeomAbs_IsoType aType    = (IsUIso ? GeomAbs_IsoU : GeomAbs_IsoV);
268     Standard_Integer      anIsoInd = anIndices->Lower();
269
270     for (; anIsoInd <= anIndices->Upper(); anIsoInd++) {
271       const Standard_Integer aHatchingIndex = anIndices->Value(anIsoInd);
272
273       if (aHatchingIndex != 0) {
274         const Standard_Real    aParam     = aParams->Value(anIsoInd);
275         const Standard_Integer aNbDomains =
276           theHatcher.GetNbDomains(aHatchingIndex);
277
278         if (aNbDomains < 0) {
279           if (IsUIso) {
280             MESSAGE("GEOMUtils_Hatcher: U iso of parameter: "<<aParam);
281           } else {
282             MESSAGE("GEOMUtils_Hatcher: V iso of parameter: "<<aParam);
283           }
284
285           switch (theHatcher.GetHatcher().Status (aHatchingIndex)) {
286           case HatchGen_NoProblem          :
287             MESSAGE("No Problem")          ; break ;
288           case HatchGen_TrimFailure        :
289             MESSAGE("Trim Failure")        ; break ;
290           case HatchGen_TransitionFailure  :
291             MESSAGE("Transition Failure")  ; break ;
292           case HatchGen_IncoherentParity   :
293             MESSAGE("Incoherent Parity")   ; break ;
294           case HatchGen_IncompatibleStates :
295             MESSAGE("Incompatible States") ; break ;
296           }
297         } else {
298           Standard_Integer anIDom = 1;
299           Standard_Real    aV1;
300           Standard_Real    aV2;
301
302           for (; anIDom <= aNbDomains; anIDom++) {
303             if (theHatcher.GetDomain(aHatchingIndex, anIDom, aV1, aV2)) {
304               DrawIso(aType, aParam, aV1, aV2, Pts, Cell,pt_start_idx);
305             }
306           }
307         }
308       }
309     }
310   }
311 }
312
313 //=======================================================================
314 // Function : MoveTo
315 // Purpose  : Init VTK ISO PLOT
316 //=======================================================================
317 void GEOM_OCCReader::MoveTo(gp_Pnt P,
318                               vtkPoints* Pts)
319 {    
320   float coord[3];
321
322   coord[0] = P.X(); coord[1] = P.Y(); coord[2] = P.Z();
323   lastVTKpoint = Pts->InsertNextPoint(coord);
324     
325
326
327 //=======================================================================
328 // Function : DrawTo
329 // Purpose  : Plot point in VTK
330 //=======================================================================
331 void GEOM_OCCReader::DrawTo(gp_Pnt P,
332                               vtkPoints* Pts,
333                               vtkCellArray* Cells)
334 {
335   float coord[3];
336   coord[0] = P.X(); coord[1] = P.Y(); coord[2] = P.Z();
337   Standard_Integer NewVTKpoint =  Pts->InsertNextPoint(coord);
338
339   vtkIdType pts[2];
340   pts[0] = lastVTKpoint;
341   pts[1] = NewVTKpoint;
342
343   Cells->InsertNextCell(2,pts);
344     
345   lastVTKpoint = NewVTKpoint;
346 }
347
348
349 //=======================================================================
350 // Function : DrawIso
351 // Purpose  : Draw an iso on vtk
352 //=======================================================================
353 void GEOM_OCCReader::DrawIso(GeomAbs_IsoType T, 
354                                Standard_Real Par, 
355                                Standard_Real T1,
356                                Standard_Real T2,
357                                vtkPoints* Pts,
358                                vtkCellArray* Cells,
359                                Standard_Integer& /*startidx*/)
360 {
361
362   Standard_Boolean halt = Standard_False;
363   Standard_Integer j,myDiscret = discretiso;
364   Standard_Real U1,U2,V1,V2,stepU=0.,stepV=0.;
365   gp_Pnt P;
366   TopLoc_Location l;
367
368   const Handle(Geom_Surface)& S = BRep_Tool::Surface(TopoDS::Face(myShape),l);
369   if (!S.IsNull()) {
370     BRepAdaptor_Surface S(TopoDS::Face(myShape),Standard_False);
371       
372     GeomAbs_SurfaceType SurfType = S.GetType();
373
374     GeomAbs_CurveType CurvType = GeomAbs_OtherCurve;
375
376     Standard_Integer Intrv, nbIntv;
377     Standard_Integer nbUIntv = S.NbUIntervals(GeomAbs_CN);
378     Standard_Integer nbVIntv = S.NbVIntervals(GeomAbs_CN);
379     TColStd_Array1OfReal TI(1,Max(nbUIntv, nbVIntv)+1);
380
381
382     if (T == GeomAbs_IsoU) {
383       S.VIntervals(TI, GeomAbs_CN);
384       V1 = Max(T1, TI(1));
385       V2 = Min(T2, TI(2));
386       U1 = Par;
387       U2 = Par;
388       stepU = 0;
389       nbIntv = nbVIntv;
390     }
391     else {
392       S.UIntervals(TI, GeomAbs_CN);
393       U1 = Max(T1, TI(1));
394       U2 = Min(T2, TI(2));
395       V1 = Par;
396       V2 = Par;
397       stepV = 0;
398       nbIntv = nbUIntv;
399     }   
400         
401     S.D0(U1,V1,P);
402     MoveTo(P,Pts);
403
404     for (Intrv = 1; Intrv <= nbIntv; Intrv++) {
405
406       if (TI(Intrv) <= T1 && TI(Intrv + 1) <= T1)
407         continue;
408       if (TI(Intrv) >= T2 && TI(Intrv + 1) >= T2)
409         continue;
410       if (T == GeomAbs_IsoU) {
411         V1 = Max(T1, TI(Intrv));
412         V2 = Min(T2, TI(Intrv + 1));
413         stepV = (V2 - V1) / myDiscret;
414       }
415       else {
416         U1 = Max(T1, TI(Intrv));
417         U2 = Min(T2, TI(Intrv + 1));
418         stepU = (U2 - U1) / myDiscret;
419       }
420
421       switch (SurfType) {
422         //-------------GeomAbs_Plane---------------
423       case GeomAbs_Plane :
424         break;
425         //----GeomAbs_Cylinder   GeomAbs_Cone------
426       case GeomAbs_Cylinder :
427       case GeomAbs_Cone :
428         if (T == GeomAbs_IsoV) {
429           for (j = 1; j < myDiscret; j++) {
430             U1 += stepU;
431             V1 += stepV;
432             S.D0(U1,V1,P);
433             DrawTo(P,Pts,Cells);
434           }
435         }
436         break;
437         //---GeomAbs_Sphere   GeomAbs_Torus--------
438         //GeomAbs_BezierSurface GeomAbs_BezierSurface
439       case GeomAbs_Sphere :
440       case GeomAbs_Torus :
441       case GeomAbs_OffsetSurface :
442       case GeomAbs_OtherSurface :
443         for (j = 1; j < myDiscret; j++) {
444           U1 += stepU;
445           V1 += stepV;
446           S.D0(U1,V1,P);
447           DrawTo(P,Pts,Cells);
448         }
449         break;
450         //-------------GeomAbs_BSplineSurface------
451       case GeomAbs_BezierSurface :
452       case GeomAbs_BSplineSurface :
453         for (j = 1; j <= myDiscret/2; j++) {
454
455           PlotCount = 0;
456
457           PlotIso ( S, T, U1, V1, (T == GeomAbs_IsoV) ? stepU*2. : stepV*2., halt, Pts, Cells);
458           U1 += stepU*2.;
459           V1 += stepV*2.;
460         }
461         break;
462         //-------------GeomAbs_SurfaceOfExtrusion--
463         //-------------GeomAbs_SurfaceOfRevolution-
464       case GeomAbs_SurfaceOfExtrusion :
465       case GeomAbs_SurfaceOfRevolution :
466         if ((T == GeomAbs_IsoV && SurfType == GeomAbs_SurfaceOfRevolution) ||
467             (T == GeomAbs_IsoU && SurfType == GeomAbs_SurfaceOfExtrusion)) {
468           if (SurfType == GeomAbs_SurfaceOfExtrusion) break;
469           for (j = 1; j < myDiscret; j++) {
470             U1 += stepU;
471             V1 += stepV;
472             S.D0(U1,V1,P);
473             DrawTo(P,Pts,Cells);
474           }
475         } else {
476           CurvType = (S.BasisCurve())->GetType();
477           switch (CurvType) {
478           case GeomAbs_Line :
479             break;
480           case GeomAbs_Circle :
481           case GeomAbs_Ellipse :
482             for (j = 1; j < myDiscret; j++) {
483               U1 += stepU;
484               V1 += stepV;
485               S.D0(U1,V1,P);
486               DrawTo(P,Pts,Cells);
487             }
488             break;
489           case GeomAbs_Parabola :
490           case GeomAbs_Hyperbola :
491           case GeomAbs_BezierCurve :
492           case GeomAbs_BSplineCurve :
493           case GeomAbs_OffsetCurve:
494           case GeomAbs_OtherCurve :
495             for (j = 1; j <= myDiscret/2; j++) {
496
497               PlotCount = 0;
498
499               PlotIso ( S, T, U1, V1,(T == GeomAbs_IsoV) ? stepU*2. : stepV*2., halt, Pts, Cells);
500               U1 += stepU*2.;
501               V1 += stepV*2.;
502             }
503             break;
504           }
505         }
506       }
507     }
508     S.D0(U2,V2,P);
509     DrawTo(P,Pts,Cells);
510   }  
511 }
512
513 //=======================================================================
514 // Function : PlotIso
515 // Purpose  : Plot iso for other surface
516 //=======================================================================
517
518 void GEOM_OCCReader::PlotIso (BRepAdaptor_Surface& S, 
519                                 GeomAbs_IsoType T,
520                                 Standard_Real& U, 
521                                 Standard_Real& V, 
522                                 Standard_Real Step, 
523                                 Standard_Boolean& halt,
524                                 vtkPoints* Pts,
525                                 vtkCellArray* Cells)
526 {
527
528   ++PlotCount; 
529
530   gp_Pnt Pl, Pr, Pm;
531
532   if (T == GeomAbs_IsoU) {
533     S.D0(U, V, Pl);
534     S.D0(U, V + Step/2., Pm);
535     S.D0(U, V + Step, Pr);
536   } else {
537     S.D0(U, V, Pl);
538     S.D0(U + Step/2., V, Pm);
539     S.D0(U + Step, V, Pr);
540   }
541
542   if (PlotCount > MaxPlotCount) {
543     DrawTo(Pr,Pts,Cells);
544     return;
545   }
546
547   if (Pm.Distance(Pl) + Pm.Distance(Pr) <= IsoRatio*Pl.Distance(Pr)) {
548     DrawTo(Pr,Pts,Cells);
549   } else 
550     if (T == GeomAbs_IsoU) {
551       PlotIso ( S, T, U, V, Step/2, halt, Pts, Cells);
552       Standard_Real aLocalV = V + Step/2 ;
553       PlotIso ( S, T, U, aLocalV , Step/2, halt, Pts, Cells);
554     } else {
555       PlotIso ( S, T, U, V, Step/2, halt, Pts, Cells);
556       Standard_Real aLocalU = U + Step/2 ;
557       PlotIso ( S, T, aLocalU , V, Step/2, halt, Pts, Cells);
558     }
559 }
560
561 //=======================================================================
562 // Function : TransferEdgeWData
563 // Purpose  : Transfer wireframe data for EDGE
564 //=======================================================================
565
566 void GEOM_OCCReader::TransferEdgeWData(const TopoDS_Edge& aEdge,
567                                          vtkPoints* Pts,
568                                          vtkCellArray* Cells)
569 {
570   Handle(Poly_PolygonOnTriangulation) aEdgePoly;
571   Standard_Integer i = 1;
572   Handle(Poly_Triangulation) T;
573   TopLoc_Location aEdgeLoc;
574   BRep_Tool::PolygonOnTriangulation(aEdge, aEdgePoly, T, aEdgeLoc, i);
575   
576   Handle(Poly_Polygon3D) P;
577   if(aEdgePoly.IsNull()) {
578     P = BRep_Tool::Polygon3D(aEdge, aEdgeLoc);
579   }
580
581   if(P.IsNull() && aEdgePoly.IsNull())
582     return;
583   
584   // Location edges
585   //---------------
586   
587   gp_Trsf edgeTransf;
588   Standard_Boolean isidtrsf = true;
589   if(!aEdgeLoc.IsIdentity())  {
590     isidtrsf = false;
591     edgeTransf = aEdgeLoc.Transformation();
592   }
593
594   gp_Pnt aP1, aP2;
595
596   Standard_Integer nbnodes;
597   if (aEdgePoly.IsNull()) {
598     nbnodes = P->NbNodes();
599     const TColgp_Array1OfPnt& theNodesP = P->Nodes();
600
601     aP1 = theNodesP(1);
602     aP2 = theNodesP(nbnodes);
603
604     float coord[3];
605     vtkIdType pts[2];
606
607     for(int j=1;j<nbnodes;j++) {
608       gp_Pnt pt1 = theNodesP(j);
609       gp_Pnt pt2 = theNodesP(j+1);
610     
611       if(!isidtrsf) {
612         // apply edge transformation
613         pt1.Transform(edgeTransf);
614         pt2.Transform(edgeTransf);
615       }
616       
617       // insert pt1
618       coord[0] = pt1.X(); coord[1] = pt1.Y(); coord[2] = pt1.Z();
619       pts[0] = Pts->InsertNextPoint(coord);
620       
621       // insert pt2
622       coord[0] = pt2.X(); coord[1] = pt2.Y(); coord[2] = pt2.Z();
623       pts[1] = Pts->InsertNextPoint(coord);
624       
625       // insert line (pt1,pt2)
626       Cells->InsertNextCell(2,pts);
627     }
628   } else {
629     nbnodes = aEdgePoly->NbNodes();
630     const TColStd_Array1OfInteger& Nodesidx = aEdgePoly->Nodes();
631
632     aP1 = T->Node(1);
633     aP2 = T->Node(nbnodes);
634
635     float coord[3];
636     vtkIdType pts[2];
637     
638     for(int j=1;j<nbnodes;j++) {
639       Standard_Integer id1 = Nodesidx(j);
640       Standard_Integer id2 = Nodesidx(j+1);
641       
642       gp_Pnt pt1 = T->Node(id1);
643       gp_Pnt pt2 = T->Node(id2);
644           
645       if(!isidtrsf) {
646         // apply edge transformation
647         pt1.Transform(edgeTransf);
648         pt2.Transform(edgeTransf);
649       }
650       
651       // insert pt1
652       coord[0] = pt1.X(); coord[1] = pt1.Y(); coord[2] = pt1.Z();
653       pts[0] = Pts->InsertNextPoint(coord);
654       
655       // insert pt2
656       coord[0] = pt2.X(); coord[1] = pt2.Y(); coord[2] = pt2.Z();
657       pts[1] = Pts->InsertNextPoint(coord);
658       
659       // insert line (pt1,pt2)
660       Cells->InsertNextCell(2,pts);
661     }
662   }
663
664   // vector representation has an arrow on its end
665   if (myIsVector)
666   {
667     if (!isidtrsf) {
668       // apply edge transformation
669       aP1.Transform(edgeTransf);
670       aP2.Transform(edgeTransf);
671     }
672
673     // draw an arrow
674     gp_Vec aDirVec (aP1, aP2);
675     Standard_Real aDist = aDirVec.Magnitude();
676     if (aDist < gp::Resolution()) return;
677     gp_Dir aDirection (aDirVec);
678
679     Standard_Real anAngle = M_PI/180. * 5.;
680     Standard_Real aLength = aDist/10.;
681
682     Standard_Real dx,dy,dz;
683     aDirection.Coord(dx,dy,dz);
684
685     // Pointe de la fleche
686     Standard_Real xo,yo,zo;
687     aP2.Coord(xo,yo,zo);
688
689     // Centre du cercle base de la fleche
690     gp_XYZ aPc = aP2.XYZ() - aDirection.XYZ() * aLength;
691
692     // Construction d'un repere i,j pour le cercle
693     gp_Dir aDirN;
694     if      (Abs(dx) <= Abs(dy) && Abs(dx) <= Abs(dz)) aDirN = gp::DX();
695     else if (Abs(dy) <= Abs(dz) && Abs(dy) <= Abs(dx)) aDirN = gp::DY();
696     else aDirN = gp::DZ();
697
698     gp_Dir aDirI = aDirection ^ aDirN;
699     gp_Dir aDirJ = aDirection ^ aDirI;
700
701     // Add points and segments, composing the arrow
702     Standard_Real cosinus, sinus, Tg = tan(anAngle);
703
704     float coord[3];
705     coord[0] = xo; coord[1] = yo; coord[2] = zo;
706
707     int ptLoc = Pts->InsertNextPoint(coord);
708     int ptFirst = 0;
709     int ptPrev = 0;
710     int ptCur = 0;
711
712     vtkIdType pts[2];
713
714     int NbPoints = 15;
715     for (int i = 1; i <= NbPoints; i++, ptPrev = ptCur)
716     {
717       cosinus = cos(2. * M_PI / NbPoints * (i-1));   
718       sinus   = sin(2. * M_PI / NbPoints * (i-1));
719
720       gp_XYZ aP = aPc + (aDirI.XYZ() * cosinus + aDirJ.XYZ() * sinus) * aLength * Tg;
721       coord[0] = aP.X();
722       coord[1] = aP.Y();
723       coord[2] = aP.Z();
724
725       // insert pts
726       ptCur = Pts->InsertNextPoint(coord);
727       pts[0] = ptCur;
728
729       if (i == 1) {
730         ptFirst = ptCur;
731       }
732       else {
733         // insert line (ptCur,ptPrev)
734         pts[1] = ptPrev;
735         Cells->InsertNextCell(2,pts);
736       }
737
738       // insert line (ptCur,ptLoc)
739       pts[1] = ptLoc;
740       Cells->InsertNextCell(2,pts);
741     }
742
743     // insert line (ptCur,ptFirst)
744     pts[0] = ptCur;
745     pts[1] = ptFirst;
746     Cells->InsertNextCell(2,pts);
747   }
748 }
749
750 /*  Standard_Integer nbnodes = aEdgePoly->NbNodes();
751   const TColStd_Array1OfInteger& Nodesidx = aEdgePoly->Nodes();
752   const TColgp_Array1OfPnt& theNodes = T->Nodes();
753     
754   float coord[3];
755   vtkIdType pts[2];
756     
757
758   // PUSH NODES
759   for(i=1;i<=nbnodes;i++) {
760     Standard_Integer id = Nodesidx(i);
761     gp_Pnt pt = theNodes(id);
762  
763     float coord[3];
764     if(!isidtrsf) pt.Transform(edgeTransf);
765
766     coord[0] = pt.X(); coord[1] = pt.Y(); coord[2] = pt.Z();
767
768     Pts->SetPoint(id-1,coord);
769
770   }
771
772   // PUSH EDGES
773   for(i=1;i<nbnodes;i++) {
774       
775     Standard_Integer id1 = Nodesidx(i);
776     Standard_Integer id2 = Nodesidx(i+1);
777     
778     vtkIdType pts[2];
779     pts[0] = id1-1; pts[1] = id2-1;
780
781     // insert line (pt1,pt2)
782     Cells->InsertNextCell(2,pts);
783   }
784  
785   
786   }*/
787
788 //=======================================================================
789 // Function : TransferVertexWData
790 // Purpose  : Transfer wireframe data for VERTEX
791 //=======================================================================
792
793 void GEOM_OCCReader::TransferVertexWData(const TopoDS_Vertex& /*aVertex*/,
794                                          vtkPoints*           Pts,
795                                          vtkCellArray*        Cells)
796 {
797 #define ZERO_COORD coord[0] = coord[1] = coord[2] = 0.0
798   
799   // gp_Pnt P = BRep_Tool::Pnt( aVertex ); ??????????????????????????
800   float delta = 1, coord[3];
801   vtkIdType pts[2];
802   // insert pt
803   ZERO_COORD; coord[0] = +delta;
804   pts[0] = Pts->InsertNextPoint(coord);
805   coord[0] = -delta;
806   pts[1] = Pts->InsertNextPoint(coord);
807   // insert line (pt1,pt2)
808   Cells->InsertNextCell(2,pts);
809
810   ZERO_COORD; coord[1] = +delta;
811   pts[0] = Pts->InsertNextPoint(coord);
812   coord[1] = -delta;
813   pts[1] = Pts->InsertNextPoint(coord);
814   // insert line (pt1,pt2)
815   Cells->InsertNextCell(2,pts);
816
817   ZERO_COORD; coord[2] = +delta;
818   pts[0] = Pts->InsertNextPoint(coord);
819   coord[2] = -delta;
820   pts[1] = Pts->InsertNextPoint(coord);
821   // insert line (pt1,pt2)
822   Cells->InsertNextCell(2,pts);
823
824 #undef ZERO_COORD
825 }       
826
827 //=======================================================================
828 // Function : TransferEdgeSData(
829 // Purpose  : Transfer shading data for EDGE
830 //=======================================================================
831
832 void GEOM_OCCReader::TransferEdgeSData(const TopoDS_Edge& /*aFace*/,
833                                        vtkPoints* /*Pts*/,
834                                        vtkCellArray* /*Cells*/) 
835 {
836 }
837
838
839 //=======================================================================
840 // Function : TransferFaceSData
841 // Purpose  : Transfer shading data for FACE
842 //=======================================================================
843 void GEOM_OCCReader::TransferFaceSData(const TopoDS_Face& aFace,
844                                          vtkPoints* Pts,
845                                          vtkCellArray* Cells) {
846
847   TopLoc_Location aLoc;
848   Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc);
849   if(aPoly.IsNull()) return;
850   else {
851     
852     gp_Trsf myTransf;
853     Standard_Boolean identity = true;
854     if(!aLoc.IsIdentity())  {
855       identity = false;
856       myTransf = aLoc.Transformation();
857     }
858
859     Standard_Integer nbNodesInFace = aPoly->NbNodes();
860     Standard_Integer nbTriInFace = aPoly->NbTriangles();
861       
862     Standard_Integer i;
863     for(i=1;i<=nbNodesInFace;i++) {
864       gp_Pnt P = aPoly->Node(i);
865       float coord[3];
866       if(!identity) P.Transform(myTransf);
867       coord[0] = P.X(); coord[1] = P.Y(); coord[2] = P.Z();
868       Pts->SetPoint(i-1,coord);
869     }
870
871     for(i=1;i<=nbTriInFace;i++) {
872       // Get the triangle
873         
874       Standard_Integer N1,N2,N3;
875       aPoly->Triangle(i).Get(N1,N2,N3);
876         
877       vtkIdType pts[3];
878       pts[0] = N1-1; pts[1] = N2-1; pts[2] = N3-1;
879       Cells->InsertNextCell(3,pts);
880
881     }
882   } 
883 }
884
885 //=======================================================================
886 // Function : ComputeShading
887 // Purpose  : Compute the shape in shading mode
888 //=======================================================================
889 void GEOM_OCCReader::ComputeShading(vtkPoints* Pts,vtkCellArray* Cells){
890
891   // Check the type of the shape:
892   if(myShape.ShapeType() == TopAbs_FACE) {
893     // Face
894     TransferFaceSData(TopoDS::Face(myShape),Pts,Cells);
895   }
896   else {
897     if(myShape.ShapeType() == TopAbs_EDGE) {
898       // Edge
899       TransferEdgeSData(TopoDS::Edge(myShape),Pts,Cells);
900     }
901     else {
902     }
903
904   } 
905
906 }
907
908 //=======================================================================
909 // Function : 
910 // Purpose  : Set parameters
911 //=======================================================================
912 void GEOM_OCCReader::setDisplayMode(int thenewmode) {
913   amode = thenewmode;
914 }
915
916 void GEOM_OCCReader::setTopo(const TopoDS_Shape& aShape, bool isVector) {
917   myShape = aShape;
918   myIsVector = isVector;
919 }
920
921 void GEOM_OCCReader::setForceUpdate(Standard_Boolean bol) {
922   forced = bol;
923 }
924
925 //=======================================================================
926 // Function : 
927 // Purpose  : Get parameters
928 //=======================================================================
929 const TopoDS_Shape& GEOM_OCCReader::getTopo() {
930   return myShape;
931 }
932
933 int GEOM_OCCReader::getDisplayMode() {
934   return amode;
935 }