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 # ifdef FC_OS_LINUX
00027 # include <unistd.h>
00028 # endif
00029 #endif
00030
00031
00032 #include "MeshAlgos.h"
00033
00034 #include <Mod/Mesh/App/Mesh.h>
00035 #include <Mod/Mesh/App/Core/MeshIO.h>
00036 #include <Mod/Mesh/App/Core/MeshKernel.h>
00037 #include <Mod/Mesh/App/Core/Iterator.h>
00038 #include <Mod/Mesh/App/Core/Algorithm.h>
00039 #include <Mod/Mesh/App/Core/TopoAlgorithm.h>
00040 #include <Mod/Mesh/App/Core/Evaluation.h>
00041
00042 #include <Base/Exception.h>
00043 #include <Base/FileInfo.h>
00044 #include <Base/Console.h>
00045 #include <Base/Builder3D.h>
00046
00047 using namespace MeshPart;
00048 using namespace MeshCore;
00049
00050
00051 void MeshAlgos::offset(MeshCore::MeshKernel* Mesh, float fSize)
00052 {
00053 std::vector<Base::Vector3f> normals = Mesh->CalcVertexNormals();
00054
00055 unsigned int i = 0;
00056
00057 for(std::vector<Base::Vector3f>::iterator It= normals.begin();It != normals.end();It++,i++)
00058
00059 Mesh->MovePoint(i,It->Normalize() * fSize);
00060 Mesh->RecalcBoundBox();
00061 }
00062
00063
00064
00065 void MeshAlgos::offsetSpecial2(MeshCore::MeshKernel* Mesh, float fSize)
00066 {
00067 Base::Builder3D builder;
00068 std::vector<Base::Vector3f> PointNormals= Mesh->CalcVertexNormals();
00069 std::vector<Base::Vector3f> FaceNormals;
00070 std::set<unsigned long> fliped;
00071
00072 MeshFacetIterator it(*Mesh);
00073 for ( it.Init(); it.More(); it.Next() )
00074 FaceNormals.push_back(it->GetNormal().Normalize());
00075
00076 unsigned int i = 0;
00077
00078
00079 for(std::vector<Base::Vector3f>::iterator It= PointNormals.begin();It != PointNormals.end();It++,i++){
00080 builder.addSingleLine(Mesh->GetPoint(i),Mesh->GetPoint(i)+It->Normalize() * fSize);
00081
00082 Mesh->MovePoint(i,It->Normalize() * fSize);
00083 }
00084 Mesh->RecalcBoundBox();
00085
00086 MeshTopoAlgorithm alg(*Mesh);
00087
00088 for(int l= 0; l<1 ;l++){
00089 for ( it.Init(),i=0; it.More(); it.Next(),i++ )
00090 {
00091 if(it->IsFlag(MeshFacet::INVALID))
00092 continue;
00093
00094 float angle = acos((FaceNormals[i] * it->GetNormal()) / (it->GetNormal().Length() * FaceNormals[i].Length()));
00095 if(angle > 1.6){
00096 builder.addSinglePoint(it->GetGravityPoint(),4,1,0,0);
00097 fliped.insert(it.Position());
00098 }
00099 }
00100
00101
00102
00103 if(fliped.size() == 0)
00104 break;
00105
00106 for(std::set<unsigned long>::iterator It= fliped.begin();It!=fliped.end();++It)
00107 alg.CollapseFacet(*It);
00108 fliped.clear();
00109 }
00110
00111 alg.Cleanup();
00112
00113
00114 MeshCore::MeshEvalSelfIntersection eval(*Mesh);
00115 std::vector<std::pair<unsigned long, unsigned long> > faces;
00116 eval.GetIntersections(faces);
00117
00118
00119 builder.saveToLog();
00120
00121 }
00122
00123 void MeshAlgos::offsetSpecial(MeshCore::MeshKernel* Mesh, float fSize, float zmax, float zmin)
00124 {
00125 std::vector<Base::Vector3f> normals = Mesh->CalcVertexNormals();
00126
00127 unsigned int i = 0;
00128
00129 for(std::vector<Base::Vector3f>::iterator It= normals.begin();It != normals.end();It++,i++)
00130 {
00131 Base::Vector3f Pnt = Mesh->GetPoint(i);
00132
00133 if(Pnt.z < zmax && Pnt.z > zmin)
00134 {
00135 Pnt.z = 0;
00136 Mesh->MovePoint(i,Pnt.Normalize() * fSize);
00137 }else
00138
00139 Mesh->MovePoint(i,It->Normalize() * fSize);
00140 }
00141 }
00142
00143
00144 void MeshAlgos::coarsen(MeshCore::MeshKernel* Mesh, float f)
00145 {
00146 #ifdef FC_USE_GTS
00147 GtsSurface * surface;
00148
00149
00150 surface = MeshAlgos::createGTSSurface(Mesh);
00151
00152 Mesh->Clear();
00153
00154 guint stop_number=100000;
00155 gdouble fold = 3.1415 / 180.;
00156
00157 gts_surface_coarsen (surface,
00158 NULL, NULL,
00159 NULL, NULL,
00160 (GtsStopFunc)gts_coarsen_stop_number,
00161 &stop_number, fold);
00162
00163
00164 fillMeshFromGTSSurface(Mesh,surface);
00165 #endif
00166 }
00167
00168
00169 MeshCore::MeshKernel* MeshAlgos::boolean(MeshCore::MeshKernel* pMesh1, MeshCore::MeshKernel* pMesh2, MeshCore::MeshKernel* pResult,int Type)
00170 {
00171 #ifdef FC_USE_GTS
00172 GtsSurface * s1, * s2, * s3;
00173 GtsSurfaceInter * si;
00174 GNode * tree1, * tree2;
00175 gboolean check_self_intersection = FALSE;
00176 gboolean closed = TRUE, is_open1, is_open2;
00177
00178
00179
00180 s1 = MeshAlgos::createGTSSurface(pMesh1);
00181 s2 = MeshAlgos::createGTSSurface(pMesh2);
00182
00183
00184
00185
00186
00187
00188 if (!gts_surface_is_orientable (s1)) {
00189 gts_object_destroy (GTS_OBJECT (s1));
00190 gts_object_destroy (GTS_OBJECT (s2));
00191 throw "surface 1 is not an orientable manifold\n" ;
00192 }
00193 if (!gts_surface_is_orientable (s2)) {
00194 gts_object_destroy (GTS_OBJECT (s1));
00195 gts_object_destroy (GTS_OBJECT (s2));
00196 throw "surface 2 is not an orientable manifold\n";
00197 }
00198
00199
00200 if (check_self_intersection) {
00201 GtsSurface * self_intersects;
00202
00203 self_intersects = gts_surface_is_self_intersecting (s1);
00204 if (self_intersects != NULL) {
00205
00206
00207
00208 gts_object_destroy (GTS_OBJECT (self_intersects));
00209 gts_object_destroy (GTS_OBJECT (s1));
00210 gts_object_destroy (GTS_OBJECT (s2));
00211 throw "surface is self-intersecting\n";
00212 }
00213 self_intersects = gts_surface_is_self_intersecting (s2);
00214 if (self_intersects != NULL) {
00215
00216
00217
00218 gts_object_destroy (GTS_OBJECT (self_intersects));
00219 gts_object_destroy (GTS_OBJECT (s1));
00220 gts_object_destroy (GTS_OBJECT (s2));
00221 throw"surface is self-intersecting\n";
00222 }
00223 }
00224
00225
00226 tree1 = gts_bb_tree_surface (s1);
00227 is_open1 = gts_surface_volume (s1) < 0. ? TRUE : FALSE;
00228
00229
00230 tree2 = gts_bb_tree_surface (s2);
00231 is_open2 = gts_surface_volume (s2) < 0. ? TRUE : FALSE;
00232
00233 si = gts_surface_inter_new (gts_surface_inter_class (),
00234 s1, s2, tree1, tree2, is_open1, is_open2);
00235 g_assert (gts_surface_inter_check (si, &closed));
00236 if (!closed) {
00237 gts_object_destroy (GTS_OBJECT (s1));
00238 gts_object_destroy (GTS_OBJECT (s2));
00239 gts_bb_tree_destroy (tree1, TRUE);
00240 gts_bb_tree_destroy (tree2, TRUE);
00241 throw"the intersection of 1 and 2 is not a closed curve\n";
00242 }
00243
00244 s3 = gts_surface_new (gts_surface_class (),
00245 gts_face_class (),
00246 gts_edge_class (),
00247 gts_vertex_class ());
00248 if (Type==0) {
00249 gts_surface_inter_boolean (si, s3, GTS_1_OUT_2);
00250 gts_surface_inter_boolean (si, s3, GTS_2_OUT_1);
00251 }
00252 else if (Type==1) {
00253 gts_surface_inter_boolean (si, s3, GTS_1_IN_2);
00254 gts_surface_inter_boolean (si, s3, GTS_2_IN_1);
00255 }
00256 else if (Type==2) {
00257 gts_surface_inter_boolean (si, s3, GTS_1_OUT_2);
00258 gts_surface_inter_boolean (si, s3, GTS_2_IN_1);
00259 gts_surface_foreach_face (si->s2, (GtsFunc) gts_triangle_revert, NULL);
00260 gts_surface_foreach_face (s2, (GtsFunc) gts_triangle_revert, NULL);
00261 }
00262 else if (Type==3) {
00263 gts_surface_inter_boolean (si, s3, GTS_1_IN_2);
00264 }
00265 else if (Type==4) {
00266 gts_surface_inter_boolean (si, s3, GTS_1_OUT_2);
00267 }
00268
00269
00270 if (check_self_intersection) {
00271 GtsSurface * self_intersects;
00272
00273 self_intersects = gts_surface_is_self_intersecting (s3);
00274 if (self_intersects != NULL) {
00275
00276
00277
00278 gts_object_destroy (GTS_OBJECT (self_intersects));
00279 gts_object_destroy (GTS_OBJECT (s1));
00280 gts_object_destroy (GTS_OBJECT (s2));
00281 gts_object_destroy (GTS_OBJECT (s3));
00282 gts_object_destroy (GTS_OBJECT (si));
00283 gts_bb_tree_destroy (tree1, TRUE);
00284 gts_bb_tree_destroy (tree2, TRUE);
00285 throw "the resulting surface is self-intersecting\n";
00286 }
00287 }
00288
00289
00290
00291
00292
00293
00294 fillMeshFromGTSSurface(pResult,s3);
00295
00296
00297
00298 gts_object_destroy (GTS_OBJECT (s1));
00299 gts_object_destroy (GTS_OBJECT (s2));
00300
00301
00302
00303
00304
00305
00306
00307 #endif
00308 return pMesh1;
00309 }
00310
00311
00312 #ifdef FC_USE_GTS
00313
00314
00316 static GtsEdge * new_edge (GtsVertex * v1, GtsVertex * v2)
00317 {
00318 GtsSegment * s = gts_vertices_are_connected (v1, v2);
00319 if( s == NULL )
00320 return gts_edge_new (gts_edge_class (), v1, v2);
00321 else
00322 return GTS_EDGE (s);
00323 }
00324
00325
00326 GtsSurface* MeshAlgos::createGTSSurface(MeshCore::MeshKernel* Mesh)
00327 {
00328 GtsSurface* Surf = gts_surface_new (gts_surface_class (),
00329 gts_face_class (),
00330 gts_edge_class (),
00331 gts_vertex_class () );
00332
00333 unsigned long p1,p2,p3;
00334 Base::Vector3f Vertex;
00335
00336
00337
00338 GtsVertex ** aVertex = (GtsVertex **) malloc(Mesh->CountPoints() * sizeof (GtsVertex *));
00339 for (unsigned int PIter = 0;PIter < Mesh->CountPoints(); PIter++)
00340 {
00341 Vertex = Mesh->GetPoint(PIter);
00342 aVertex[PIter] = gts_vertex_new (gts_vertex_class (), Vertex.x, Vertex.y, Vertex.z);
00343 }
00344
00345
00346 for (unsigned int pFIter = 0;pFIter < Mesh->CountFacets(); pFIter++)
00347 {
00348
00349 Mesh->GetFacetPoints(pFIter,p1,p2,p3);
00350
00351
00352 gts_surface_add_face (Surf,
00353 gts_face_new (Surf->face_class,
00354 new_edge (aVertex[p1],aVertex[p2]),
00355 new_edge (aVertex[p2],aVertex[p3]),
00356 new_edge (aVertex[p3],aVertex[p1])));
00357 }
00358
00359 Base::Console().Log("GTS [%d faces, %d Points, %d Edges,%s ,%s]\n",gts_surface_face_number(Surf),
00360 gts_surface_vertex_number(Surf),
00361 gts_surface_edge_number(Surf),
00362 gts_surface_is_orientable (Surf)?"orientable":"not orientable",
00363 gts_surface_is_self_intersecting(Surf)?"self-intersections":"no self-intersection" );
00364
00365 return Surf;
00366
00367 }
00368
00370 static void onFaces (GtsTriangle * t, std::vector<MeshGeomFacet> *VAry )
00371 {
00372 GtsVertex *mv0,*mv1,*mv2;
00373
00374 gts_triangle_vertices (t,&mv0,&mv1,&mv2);
00375
00376 VAry->push_back(MeshGeomFacet(Base::Vector3f(mv0->p.x,mv0->p.y,mv0->p.z),
00377 Base::Vector3f(mv1->p.x,mv1->p.y,mv1->p.z),
00378 Base::Vector3f(mv2->p.x,mv2->p.y,mv2->p.z)));
00379
00380 }
00381
00382
00383
00384
00385
00386
00387
00388 void MeshAlgos::fillMeshFromGTSSurface(MeshCore::MeshKernel* pMesh, GtsSurface* pSurface)
00389 {
00390 std::vector<MeshGeomFacet> VAry;
00391
00392
00393 pMesh->Clear();
00394
00395
00396 gts_surface_foreach_face (pSurface, (GtsFunc) onFaces,&VAry);
00397
00398
00399 gts_object_destroy (GTS_OBJECT (pSurface));
00400
00401
00402 (*pMesh) = VAry;
00403
00404 }
00405
00406 #endif
00407
00408 #include <TopExp_Explorer.hxx>
00409 #include <TopExp.hxx>
00410 #include <TopoDS_Edge.hxx>
00411 #include <TopoDS_Vertex.hxx>
00412 #include <TopoDS_Wire.hxx>
00413 #include <TopoDS.hxx>
00414 #include <Geom_Curve.hxx>
00415 #include <Geom_Plane.hxx>
00416 #include <BRep_Tool.hxx>
00417 #include <GeomAPI_IntCS.hxx>
00418 #include <GeomLProp_CLProps.hxx>
00419
00420 void MeshAlgos::cutByShape(const TopoDS_Shape &aShape,const MeshCore::MeshKernel* pMesh,MeshCore::MeshKernel* pToolMesh)
00421 {
00422
00423
00424
00425 CurveProjectorWithToolMesh Project(aShape,*pMesh,*pToolMesh);
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 }
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446 void MeshAlgos::cutByCurve(MeshCore::MeshKernel* pMesh,const std::vector<CurveProjector::FaceSplitEdge> &vSplitEdges)
00447 {
00448 MeshTopoAlgorithm cTopAlg(*pMesh);
00449
00450 for (std::vector<CurveProjector::FaceSplitEdge>::const_iterator it = vSplitEdges.begin();it!=vSplitEdges.end();++it)
00451 {
00452 cTopAlg.SplitFacet( it->ulFaceIndex, it->p1, it->p2 );
00453 }
00454 }
00455
00456 class _VertexCompare
00457 {
00458 public:
00459 bool operator () (const TopoDS_Vertex &rclV1, const TopoDS_Vertex &rclV2) const
00460 {
00461 if (rclV1.IsSame(rclV2) == Standard_True)
00462 return false;
00463
00464 gp_XYZ clP1 = BRep_Tool::Pnt(rclV1).XYZ();
00465 gp_XYZ clP2 = BRep_Tool::Pnt(rclV2).XYZ();
00466
00467 if (fabs(clP1.X() - clP2.X()) < dE)
00468 {
00469 if (fabs(clP1.Y() - clP2.Y()) < dE)
00470 return clP1.Z() < clP2.Z();
00471 else
00472 return clP1.Y() < clP2.Y();
00473 }
00474 else
00475 return clP1.X() < clP2.X();
00476 }
00477
00478 _VertexCompare (void) : dE(1.0e-5) {}
00479 double dE;
00480 };
00481
00482
00483
00484 void MeshAlgos::LoftOnCurve(MeshCore::MeshKernel &ResultMesh, const TopoDS_Shape &Shape, const std::vector<Base::Vector3f> &poly, const Base::Vector3f & up, float MaxSize)
00485 {
00486 TopExp_Explorer Ex;
00487 Standard_Real fBegin, fEnd;
00488 std::vector<MeshGeomFacet> cVAry;
00489 std::map<TopoDS_Vertex,std::vector<Base::Vector3f>,_VertexCompare> ConnectMap;
00490
00491 for (Ex.Init(Shape, TopAbs_EDGE); Ex.More(); Ex.Next())
00492 {
00493
00494 TopoDS_Edge Edge = (TopoDS_Edge&)Ex.Current();
00495 TopoDS_Vertex V1, V2;
00496 TopExp::Vertices(Edge, V1, V2);
00497 bool bBegin = false,bEnd = false;
00498
00499 GeomLProp_CLProps prop(BRep_Tool::Curve(Edge,fBegin,fEnd),1,0.0000000001);
00500 int res = int((fEnd - fBegin)/MaxSize);
00501
00502 if(res < 2)
00503 res = 2;
00504 gp_Dir Tangent;
00505
00506 std::vector<Base::Vector3f> prePoint(poly.size());
00507 std::vector<Base::Vector3f> actPoint(poly.size());
00508
00509
00510 if(ConnectMap.find(V1) != ConnectMap.end() ){
00511 bBegin = true;
00512 prePoint = ConnectMap[V1];
00513 }
00514
00515 if(ConnectMap.find(V2) != ConnectMap.end() )
00516 bEnd = true;
00517
00518 for (long i = 0; i < res; i++)
00519 {
00520
00521
00522 prop.SetParameter(fBegin + ((fEnd - fBegin) * float(i)) / float(res-1));
00523 prop.Tangent(Tangent);
00524 Base::Vector3f Tng((float)Tangent.X(),
00525 (float)Tangent.Y(),
00526 (float)Tangent.Z());
00527 Base::Vector3f Ptn((float)prop.Value().X(),
00528 (float)prop.Value().Y(),
00529 (float)prop.Value().Z());
00530 Base::Vector3f Up (up);
00531
00532 Tng.Normalize();
00533 Up.Normalize();
00534 Base::Vector3f Third(Tng%Up);
00535
00536
00537
00538 unsigned int l=0;
00539 std::vector<Base::Vector3f>::const_iterator It;
00540
00541
00542 for(It=poly.begin();It!=poly.end();++It,l++)
00543 actPoint[l] = ((Third*It->x)+(Up*It->y)+(Tng*It->z)+Ptn);
00544
00545 if(i == res-1 && !bEnd)
00546
00547 ConnectMap[V2] = actPoint;
00548
00549 if(i==1 && bBegin)
00550
00551 prePoint = ConnectMap[V1];
00552
00553 if(i==0 && !bBegin)
00554
00555 ConnectMap[V1] = actPoint;
00556
00557 if(i )
00558 {
00559 for(l=0;l<actPoint.size();l++)
00560 {
00561 if(l)
00562 {
00563 if(i == res-1 && bEnd)
00564 actPoint = ConnectMap[V2];
00565
00566 Base::Vector3f p1 = prePoint[l-1],
00567 p2 = actPoint[l-1],
00568 p3 = prePoint[l],
00569 p4 = actPoint[l];
00570
00571 cVAry.push_back(MeshGeomFacet(p1,p2,p3));
00572 cVAry.push_back(MeshGeomFacet(p3,p2,p4));
00573 }
00574 }
00575 }
00576
00577 prePoint = actPoint;
00578 }
00579 }
00580
00581 ResultMesh.AddFacets(cVAry);
00582
00583 }