00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "PreCompiled.h"
00025 #ifndef _PreComp_
00026 # include <algorithm>
00027 # include <map>
00028 #endif
00029 #ifdef FC_USE_OCC
00030 # include <Bnd_Box.hxx>
00031 # include <BndLib_Add3dCurve.hxx>
00032 # include <BRep_Tool.hxx>
00033 # include <BRepAdaptor_Curve.hxx>
00034 # include <GCPnts_UniformDeflection.hxx>
00035 # include <Geom_Curve.hxx>
00036 # include <Geom_Plane.hxx>
00037 # include <GeomAPI_IntCS.hxx>
00038 # include <gp_Pln.hxx>
00039 # include <TopExp_Explorer.hxx>
00040 # include <TopoDS.hxx>
00041 # include <TopoDS_Edge.hxx>
00042
00043 #include "Projection.h"
00044 #include "MeshKernel.h"
00045 #include "Iterator.h"
00046 #include "Algorithm.h"
00047 #include "Grid.h"
00048
00049 #include <Base/Exception.h>
00050 #include <Base/Console.h>
00051 #include <Base/Sequencer.h>
00052
00053
00054 using namespace MeshCore;
00055
00056
00057 MeshProjection::MeshProjection(const MeshKernel& rMesh)
00058 : _rcMesh(rMesh)
00059 {
00060 }
00061
00062 MeshProjection::~MeshProjection()
00063 {
00064 }
00065
00066 void MeshProjection::splitMeshByShape ( const TopoDS_Shape &aShape, float fMaxDist ) const
00067 {
00068 std::vector<SplitEdge> cSplitEdges;
00069 projectToMesh( aShape, fMaxDist, cSplitEdges );
00070
00071 std::ofstream str("output.asc", std::ios::out | std::ios::binary);
00072 str.precision(4);
00073 str.setf(std::ios::fixed | std::ios::showpoint);
00074 for (std::vector<SplitEdge>::const_iterator it = cSplitEdges.begin();it!=cSplitEdges.end();++it) {
00075 str << it->cPt.x << " " << it->cPt.y << " " << it->cPt.z << std::endl;
00076 }
00077 str.close();
00078 }
00079
00080 void MeshProjection::projectToMesh ( const TopoDS_Shape &aShape, float fMaxDist, std::vector<SplitEdge>& rSplitEdges ) const
00081 {
00082
00083 MeshAlgorithm clAlg( _rcMesh );
00084 float fAvgLen = clAlg.GetAverageEdgeLength();
00085 MeshFacetGrid cGrid( _rcMesh, 5.0f*fAvgLen );
00086
00087 TopExp_Explorer Ex;
00088 TopoDS_Shape Edge;
00089
00090 int iCnt=0;
00091 for (Ex.Init(aShape, TopAbs_EDGE); Ex.More(); Ex.Next())
00092 iCnt++;
00093
00094 Base::Sequencer().start( "Project curve on mesh", iCnt );
00095
00096 for (Ex.Init(aShape, TopAbs_EDGE); Ex.More(); Ex.Next()) {
00097 const TopoDS_Edge& aEdge = TopoDS::Edge(Ex.Current());
00098 projectEdgeToEdge( aEdge, fMaxDist, cGrid, rSplitEdges );
00099 Base::Sequencer().next();
00100 }
00101
00102 Base::Sequencer().stop();
00103 }
00104
00105 void MeshProjection::projectEdgeToEdge( const TopoDS_Edge &aEdge, float fMaxDist, const MeshFacetGrid& rGrid,
00106 std::vector<SplitEdge>& rSplitEdges ) const
00107 {
00108 std::vector<unsigned long> auFInds;
00109 std::map<std::pair<unsigned long, unsigned long>, std::list<unsigned long> > pEdgeToFace;
00110 const std::vector<MeshFacet>& rclFAry = _rcMesh.GetFacets();
00111
00112
00113 std::vector<Vector3f> acPolyLine;
00114
00115 BRepAdaptor_Curve clCurve( aEdge );
00116
00117 Standard_Real fFirst = clCurve.FirstParameter();
00118 Standard_Real fLast = clCurve.LastParameter();
00119
00120 GCPnts_UniformDeflection clDefl(clCurve, 0.01f, fFirst, fLast);
00121 if (clDefl.IsDone() == Standard_True) {
00122 Standard_Integer nNbPoints = clDefl.NbPoints();
00123 for (Standard_Integer i = 1; i <= nNbPoints; i++) {
00124 gp_Pnt gpPt = clCurve.Value(clDefl.Parameter(i));
00125 acPolyLine.push_back( Vector3f( (float)gpPt.X(), (float)gpPt.Y(), (float)gpPt.Z() ) );
00126 }
00127 }
00128
00129 MeshAlgorithm(_rcMesh).SearchFacetsFromPolyline( acPolyLine, fMaxDist, rGrid, auFInds);
00130
00131 std::sort(auFInds.begin(), auFInds.end());
00132 auFInds.erase(std::unique(auFInds.begin(), auFInds.end()), auFInds.end());
00133
00134
00135 for ( std::vector<unsigned long>::iterator pI = auFInds.begin(); pI != auFInds.end(); ++pI ) {
00136 const MeshFacet& rF = rclFAry[*pI];
00137 for (int i = 0; i < 3; i++) {
00138 unsigned long ulPt0 = std::min<unsigned long>(rF._aulPoints[i], rF._aulPoints[(i+1)%3]);
00139 unsigned long ulPt1 = std::max<unsigned long>(rF._aulPoints[i], rF._aulPoints[(i+1)%3]);
00140 pEdgeToFace[std::pair<unsigned long, unsigned long>(ulPt0, ulPt1)].push_front(*pI);
00141 }
00142 }
00143
00144
00145 std::map<Quantity_Parameter, SplitEdge> rParamSplitEdges;
00146
00147
00148 Handle(Geom_Curve) hCurve = BRep_Tool::Curve( aEdge,fFirst,fLast );
00149
00150
00151
00152
00153
00154 MeshPointIterator cPI( _rcMesh );
00155 MeshFacetIterator cFI( _rcMesh );
00156
00157 Base::Sequencer().start( "Project curve on mesh", pEdgeToFace.size() );
00158 std::map<std::pair<unsigned long, unsigned long>, std::list<unsigned long> >::iterator it;
00159 for ( it = pEdgeToFace.begin(); it != pEdgeToFace.end(); ++it ) {
00160 Base::Sequencer().next();
00161
00162
00163 unsigned long uE0 = it->first.first;
00164 cPI.Set( uE0 );
00165 Vector3f cE0 = *cPI;
00166 unsigned long uE1 = it->first.second;
00167 cPI.Set( uE1 );
00168 Vector3f cE1 = *cPI;
00169
00170 const std::list<unsigned long>& auFaces = it->second;
00171 if ( auFaces.size() > 2 )
00172 continue;
00173
00174
00175
00176 Vector3f cEdgeNormal;
00177 for ( std::list<unsigned long>::const_iterator itF = auFaces.begin(); itF != auFaces.end(); ++itF ) {
00178 cFI.Set( *itF );
00179 cEdgeNormal += cFI->GetNormal();
00180 }
00181
00182
00183 Vector3f cPlaneNormal = cEdgeNormal % (cE1 - cE0);
00184 Handle(Geom_Plane) hPlane = new Geom_Plane(gp_Pln(gp_Pnt(cE0.x,cE0.y,cE0.z),
00185 gp_Dir(cPlaneNormal.x,cPlaneNormal.y,cPlaneNormal.z)));
00186
00187
00188 GeomAPI_IntCS Alg(hCurve,hPlane);
00189 if ( Alg.IsDone() ) {
00190 Standard_Integer nNbPoints = Alg.NbPoints();
00191 if ( nNbPoints == 1 ) {
00192 Quantity_Parameter fU, fV, fW;
00193 Alg.Parameters( 1, fU, fV, fW);
00194
00195 gp_Pnt P = Alg.Point(1);
00196 Vector3f cP0((float)P.X(), (float)P.Y(), (float)P.Z());
00197
00198 float l = ( (cP0 - cE0) * (cE1 - cE0) ) / ( (cE1 - cE0) * ( cE1 - cE0) );
00199
00200
00201 if ( l>=0.0f && l<=1.0f ) {
00202 Vector3f cSplitPoint = (1-l) * cE0 + l * cE1;
00203 float fDist = Base::Distance( cP0, cSplitPoint );
00204
00205 if ( fDist <= fMaxDist ) {
00206 SplitEdge splitEdge;
00207 splitEdge.uE0 = uE0;
00208 splitEdge.uE1 = uE1;
00209 splitEdge.cPt = cSplitPoint;
00210 rParamSplitEdges[fW] = splitEdge;
00211 }
00212 }
00213 }
00214
00215 else if ( nNbPoints > 1 ) {
00216 int nCntSol=0;
00217 Vector3f cSplitPoint;
00218 Quantity_Parameter fSol;
00219 Vector3f cP0;
00220 for ( int j=1; j<=nNbPoints; j++ ) {
00221 Quantity_Parameter fU, fV, fW;
00222 Alg.Parameters( j, fU, fV, fW);
00223 gp_Pnt P = Alg.Point(j);
00224 cP0.Set((float)P.X(), (float)P.Y(), (float)P.Z());
00225
00226 float l = ( (cP0 - cE0) * (cE1 - cE0) ) / ( (cE1 - cE0) * ( cE1 - cE0) );
00227
00228
00229 if ( l>=0.0 && l<=1.0 ) {
00230 cSplitPoint = (1-l) * cE0 + l * cE1;
00231 float fDist = Base::Distance( cP0, cSplitPoint );
00232
00233 if (fDist <= fMaxDist) {
00234 nCntSol++;
00235 fSol = fW;
00236 }
00237 }
00238 }
00239
00240
00241 if ( nCntSol == 1 ) {
00242 SplitEdge splitEdge;
00243 splitEdge.uE0 = uE0;
00244 splitEdge.uE1 = uE1;
00245 splitEdge.cPt = cSplitPoint;
00246 rParamSplitEdges[fSol] = splitEdge;
00247 }
00248 else if ( nCntSol > 1 ) {
00249 Base::Console().Log("More than one possible intersection points\n");
00250 }
00251 }
00252 }
00253 }
00254
00255
00256 for (std::map<Quantity_Parameter, SplitEdge>::iterator itS =
00257 rParamSplitEdges.begin(); itS != rParamSplitEdges.end(); ++itS) {
00258 rSplitEdges.push_back( itS->second );
00259 }
00260
00261 Base::Sequencer().stop();
00262 }
00263
00264 #endif