Back to index

salome-geom  6.5.0
GEOM_EdgeSource.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 #include "GEOM_EdgeSource.h" 
00021  
00022 #include <vtkObjectFactory.h> 
00023 
00024 #include <vtkPoints.h> 
00025 #include <vtkCellArray.h> 
00026 
00027 #include <BRep_Tool.hxx>
00028 #include <Poly_Polygon3D.hxx>
00029 #include <Poly_Triangulation.hxx>
00030 #include <TColStd_Array1OfInteger.hxx>
00031 #include <Poly_PolygonOnTriangulation.hxx>
00032 #include <GeomAdaptor_Curve.hxx>
00033 #include <GCPnts_AbscissaPoint.hxx>
00034  
00035 #include <vtkStripper.h>  
00036 #include <vtkPolyData.h>  
00037 
00038 vtkStandardNewMacro(GEOM_EdgeSource);
00039  
00040 GEOM_EdgeSource::GEOM_EdgeSource() :
00041   myIsVector(false)
00042 { 
00043 } 
00044  
00045 GEOM_EdgeSource::~GEOM_EdgeSource() 
00046 { 
00047 } 
00048 
00049 void GEOM_EdgeSource::AddEdge (const TopoDS_Edge& theEdge,
00050                                bool theIsVector)
00051 {
00052   myEdgeSet.Add(theEdge);
00053   myIsVector = theIsVector;
00054 }
00055 
00056 void
00057 GEOM_EdgeSource:: 
00058 Execute()
00059 {
00060   vtkPolyData* aPolyData = GetOutput();
00061   aPolyData->Allocate();
00062   vtkPoints* aPts = vtkPoints::New();
00063   aPolyData->SetPoints(aPts);
00064   aPts->Delete();
00065 
00066   TEdgeSet::Iterator anIter (myEdgeSet);
00067   for (; anIter.More(); anIter.Next()) {
00068     TopoDS_Edge anEdge = anIter.Value();
00069     if ( !myIsVector )
00070       // draw curve direction (issue 0021087)
00071       anEdge.Orientation( TopAbs_FORWARD );
00072     OCC2VTK(anEdge,aPolyData,aPts,myIsVector||myIsVectorMode);
00073   }
00074 }
00075 
00076 void GEOM_EdgeSource::OCC2VTK (const TopoDS_Edge& theEdge,  
00077                                vtkPolyData* thePolyData, 
00078                                vtkPoints* thePts,
00079                                bool theIsVector) 
00080 {
00081   Handle(Poly_PolygonOnTriangulation) aEdgePoly;
00082   Standard_Integer i = 1;
00083   Handle(Poly_Triangulation) T;
00084   TopLoc_Location aEdgeLoc;
00085   BRep_Tool::PolygonOnTriangulation(theEdge, aEdgePoly, T, aEdgeLoc, i);
00086 
00087   Handle(Poly_Polygon3D) P;
00088   if(aEdgePoly.IsNull())
00089     P = BRep_Tool::Polygon3D(theEdge, aEdgeLoc);
00090 
00091   if(P.IsNull() && aEdgePoly.IsNull())
00092     return;
00093   
00094   // Location edges
00095   //---------------
00096   gp_Trsf edgeTransf;
00097   Standard_Boolean isidtrsf = true;
00098   if(!aEdgeLoc.IsIdentity())  {
00099     isidtrsf = false;
00100     edgeTransf = aEdgeLoc.Transformation();
00101   }
00102 
00103   gp_Pnt aP1, aP2;
00104 
00105   if (aEdgePoly.IsNull()) {
00106     Standard_Integer aNbNodes = P->NbNodes();
00107     const TColgp_Array1OfPnt& aNodesP = P->Nodes();
00108 
00109     aP1 = aNodesP(1);
00110     aP2 = aNodesP(aNbNodes);
00111 
00112     for (int j = 1; j < aNbNodes; j++) {
00113       gp_Pnt pt1 = aNodesP(j);
00114       gp_Pnt pt2 = aNodesP(j+1);
00115 
00116       if (!isidtrsf) {
00117         // apply edge transformation
00118         pt1.Transform(edgeTransf);
00119         pt2.Transform(edgeTransf);
00120       }
00121 
00122       float aCoord1[3] = {pt1.X(), pt1.Y(), pt1.Z()};
00123       vtkIdType anIds[2];
00124       anIds[0] = thePts->InsertNextPoint(aCoord1);
00125 
00126       float aCoord2[3] = {pt2.X(), pt2.Y(), pt2.Z()};
00127       anIds[1] = thePts->InsertNextPoint(aCoord2);
00128 
00129       thePolyData->InsertNextCell(VTK_LINE,2,anIds);
00130     }
00131   } else {
00132     Standard_Integer aNbNodes = aEdgePoly->NbNodes();
00133     const TColStd_Array1OfInteger& aNodeIds = aEdgePoly->Nodes();
00134     const TColgp_Array1OfPnt& anId2Pnts = T->Nodes();
00135 
00136     aP1 = anId2Pnts(aNodeIds(1));
00137     aP2 = anId2Pnts(aNodeIds(aNbNodes));
00138 
00139     for(int j = 1; j < aNbNodes; j++) {
00140       Standard_Integer id1 = aNodeIds(j);
00141       Standard_Integer id2 = aNodeIds(j+1);
00142       
00143       gp_Pnt pt1 = anId2Pnts(id1);
00144       gp_Pnt pt2 = anId2Pnts(id2);
00145           
00146       if(!isidtrsf) {
00147         // apply edge transformation
00148         pt1.Transform(edgeTransf);
00149         pt2.Transform(edgeTransf);
00150       }
00151       
00152       float aCoord1[3] = {pt1.X(), pt1.Y(), pt1.Z()};
00153       vtkIdType anIds[2];
00154       anIds[0] = thePts->InsertNextPoint(aCoord1);
00155 
00156       float aCoord2[3] = {pt2.X(), pt2.Y(), pt2.Z()};
00157       anIds[1] = thePts->InsertNextPoint(aCoord2);
00158 
00159       thePolyData->InsertNextCell(VTK_LINE,2,anIds);
00160     }
00161   }
00162 
00163   
00164   // vector representation has an arrow on its end
00165   if (theIsVector)
00166   {
00167     if (!isidtrsf) {
00168       // apply edge transformation
00169       aP1.Transform(edgeTransf);
00170       aP2.Transform(edgeTransf);
00171     }
00172 
00173     // draw an arrow
00174 
00175     double fp,lp;
00176     gp_Vec aDirVec;
00177     Handle(Geom_Curve) C = BRep_Tool::Curve(theEdge,fp,lp);
00178     if ( theEdge.Orientation() == TopAbs_FORWARD ) {
00179       C->D1(lp, aP2, aDirVec);
00180     } else {
00181       C->D1(fp, aP1, aDirVec);
00182       aP2 = aP1;
00183     }
00184 
00185     GeomAdaptor_Curve aAdC;
00186     aAdC.Load(C, fp, lp);
00187     Standard_Real aDist = GCPnts_AbscissaPoint::Length(aAdC, fp, lp); 
00188     if (aDist < gp::Resolution()) return;
00189 
00190     gp_Dir aDirection;
00191 
00192     if ( theEdge.Orientation() == TopAbs_FORWARD )
00193       aDirection = aDirVec;
00194     else
00195       aDirection = -aDirVec;
00196 
00197     Standard_Real anAngle = M_PI/180.*5.;
00198     Standard_Real aLength = aDist/10.;
00199 
00200     Standard_Real dx,dy,dz;
00201     aDirection.Coord(dx,dy,dz);
00202 
00203     // Arrow Point
00204     Standard_Real xo,yo,zo;
00205     aP2.Coord(xo,yo,zo);
00206 
00207     // Center of circle that arrow based
00208     gp_XYZ aPc = aP2.XYZ() - aDirection.XYZ() * aLength;
00209 
00210     // Construction of the base vectors for the arrow circle
00211     gp_Dir aDirN;
00212     if      (Abs(dx) <= Abs(dy) && Abs(dx) <= Abs(dz)) aDirN = gp::DX();
00213     else if (Abs(dy) <= Abs(dz) && Abs(dy) <= Abs(dx)) aDirN = gp::DY();
00214     else aDirN = gp::DZ();
00215 
00216     gp_Dir aDirI = aDirection ^ aDirN;
00217     gp_Dir aDirJ = aDirection ^ aDirI;
00218 
00219     // Add points and segments, composing the arrow
00220     Standard_Real cosinus, sinus, Tg = tan(anAngle);
00221 
00222     float coord[3] = {xo, yo, zo};
00223 
00224     vtkIdType ptLoc = thePts->InsertNextPoint(coord);
00225     vtkIdType ptFirst = 0;
00226     vtkIdType ptPrev = 0;
00227     vtkIdType ptCur = 0;
00228 
00229     vtkIdType pts[2];
00230 
00231     int NbPoints = 15;
00232     for (int i = 1; i <= NbPoints; i++, ptPrev = ptCur)
00233     {
00234       cosinus = cos(2. * M_PI / NbPoints * (i-1));   
00235       sinus   = sin(2. * M_PI / NbPoints * (i-1));
00236 
00237       gp_XYZ aP = aPc + (aDirI.XYZ() * cosinus + aDirJ.XYZ() * sinus) * aLength * Tg;
00238       coord[0] = aP.X();
00239       coord[1] = aP.Y();
00240       coord[2] = aP.Z();
00241 
00242       // insert pts
00243       ptCur = thePts->InsertNextPoint(coord);
00244       pts[0] = ptCur;
00245 
00246       if (i == 1) {
00247         ptFirst = ptCur;
00248       }
00249       else {
00250         // insert line (ptCur,ptPrev)
00251         pts[1] = ptPrev;
00252         thePolyData->InsertNextCell(VTK_LINE,2,pts);
00253       }
00254 
00255       // insert line (ptCur,ptLoc)
00256       pts[1] = ptLoc;
00257       thePolyData->InsertNextCell(VTK_LINE,2,pts);
00258     }
00259 
00260     // insert line (ptCur,ptFirst)
00261     pts[0] = ptCur;
00262     pts[1] = ptFirst;
00263     thePolyData->InsertNextCell(VTK_LINE,2,pts);
00264   }
00265 }
00266 
00267 void GEOM_EdgeSource::SetVectorMode (bool theMode)
00268 {
00269   myIsVectorMode = theMode;
00270 }
00271 
00272 bool GEOM_EdgeSource::GetVectorMode ()
00273 {
00274   return !myIsVector && myIsVectorMode;
00275 }