23
#include "PreCompiled.h"
30
#include <Base/Builder3D.h>
31
#include <Base/Console.h>
32
#include <Mod/Mesh/App/Core/Evaluation.h>
33
#include <Mod/Mesh/App/Core/Iterator.h>
34
#include <Mod/Mesh/App/Core/MeshKernel.h>
35
#include <Mod/Mesh/App/Core/TopoAlgorithm.h>
40
using namespace MeshPart;
41
using namespace MeshCore;
44
void MeshAlgos::offset(MeshCore::MeshKernel* Mesh, float fSize)
46
std::vector<Base::Vector3f> normals = Mesh->CalcVertexNormals();
50
for (std::vector<Base::Vector3f>::iterator It = normals.begin(); It != normals.end();
53
Mesh->MovePoint(i, It->Normalize() * fSize);
55
Mesh->RecalcBoundBox();
59
void MeshAlgos::offsetSpecial2(MeshCore::MeshKernel* Mesh, float fSize)
61
Base::Builder3D builder;
62
std::vector<Base::Vector3f> PointNormals = Mesh->CalcVertexNormals();
63
std::vector<Base::Vector3f> FaceNormals;
64
std::set<MeshCore::FacetIndex> fliped;
66
MeshFacetIterator it(*Mesh);
67
for (it.Init(); it.More(); it.Next()) {
68
FaceNormals.push_back(it->GetNormal().Normalize());
74
for (std::vector<Base::Vector3f>::iterator It = PointNormals.begin(); It != PointNormals.end();
76
Base::Line3f line {Mesh->GetPoint(i), Mesh->GetPoint(i) + It->Normalize() * fSize};
77
Base::DrawStyle drawStyle;
78
builder.addNode(Base::LineItem {line, drawStyle});
80
Mesh->MovePoint(i, It->Normalize() * fSize);
82
Mesh->RecalcBoundBox();
84
MeshTopoAlgorithm alg(*Mesh);
86
for (int l = 0; l < 1; l++) {
87
for (it.Init(), i = 0; it.More(); it.Next(), i++) {
88
if (it->IsFlag(MeshFacet::INVALID)) {
92
float angle = acos((FaceNormals[i] * it->GetNormal())
93
/ (it->GetNormal().Length() * FaceNormals[i].Length()));
95
Base::DrawStyle drawStyle;
96
drawStyle.pointSize = 4.0F;
97
Base::PointItem item {it->GetGravityPoint(),
99
Base::ColorRGB {1.0F, 0.0F, 0.0F}};
100
builder.addNode(item);
101
fliped.insert(it.Position());
107
if (fliped.empty()) {
111
for (MeshCore::FacetIndex It : fliped) {
112
alg.CollapseFacet(It);
120
MeshCore::MeshEvalSelfIntersection eval(*Mesh);
121
std::vector<std::pair<MeshCore::FacetIndex, MeshCore::FacetIndex>> faces;
122
eval.GetIntersections(faces);
128
void MeshAlgos::offsetSpecial(MeshCore::MeshKernel* Mesh, float fSize, float zmax, float zmin)
130
std::vector<Base::Vector3f> normals = Mesh->CalcVertexNormals();
134
for (std::vector<Base::Vector3f>::iterator It = normals.begin(); It != normals.end();
136
Base::Vector3f Pnt = Mesh->GetPoint(i);
138
if (Pnt.z < zmax && Pnt.z > zmin) {
140
Mesh->MovePoint(i, Pnt.Normalize() * fSize);
144
Mesh->MovePoint(i, It->Normalize() * fSize);
150
void MeshAlgos::coarsen(MeshCore::MeshKernel* , float )
156
surface = MeshAlgos::createGTSSurface(Mesh);
160
guint stop_number = 100000;
161
gdouble fold = 3.1415 / 180.;
163
gts_surface_coarsen(surface,
168
(GtsStopFunc)gts_coarsen_stop_number,
173
fillMeshFromGTSSurface(Mesh, surface);
178
MeshCore::MeshKernel* MeshAlgos::boolean(MeshCore::MeshKernel* pMesh1,
179
MeshCore::MeshKernel* ,
180
MeshCore::MeshKernel* ,
184
GtsSurface *s1, *s2, *s3;
186
GNode *tree1, *tree2;
187
gboolean check_self_intersection = false;
188
gboolean closed = true, is_open1, is_open2;
192
s1 = MeshAlgos::createGTSSurface(pMesh1);
193
s2 = MeshAlgos::createGTSSurface(pMesh2);
200
if (!gts_surface_is_orientable(s1)) {
201
gts_object_destroy(GTS_OBJECT(s1));
202
gts_object_destroy(GTS_OBJECT(s2));
203
throw std::runtime_error("surface 1 is not an orientable manifold\n");
205
if (!gts_surface_is_orientable(s2)) {
206
gts_object_destroy(GTS_OBJECT(s1));
207
gts_object_destroy(GTS_OBJECT(s2));
208
throw std::runtime_error("surface 2 is not an orientable manifold\n");
212
if (check_self_intersection) {
213
GtsSurface* self_intersects;
215
self_intersects = gts_surface_is_self_intersecting(s1);
216
if (self_intersects != NULL) {
220
gts_object_destroy(GTS_OBJECT(self_intersects));
221
gts_object_destroy(GTS_OBJECT(s1));
222
gts_object_destroy(GTS_OBJECT(s2));
223
throw std::runtime_error("surface is self-intersecting\n");
225
self_intersects = gts_surface_is_self_intersecting(s2);
226
if (self_intersects != NULL) {
230
gts_object_destroy(GTS_OBJECT(self_intersects));
231
gts_object_destroy(GTS_OBJECT(s1));
232
gts_object_destroy(GTS_OBJECT(s2));
233
throw std::runtime_error("surface is self-intersecting\n");
238
tree1 = gts_bb_tree_surface(s1);
239
is_open1 = gts_surface_volume(s1) < 0. ? true : false;
242
tree2 = gts_bb_tree_surface(s2);
243
is_open2 = gts_surface_volume(s2) < 0. ? true : false;
245
si = gts_surface_inter_new(gts_surface_inter_class(), s1, s2, tree1, tree2, is_open1, is_open2);
246
g_assert(gts_surface_inter_check(si, &closed));
248
gts_object_destroy(GTS_OBJECT(s1));
249
gts_object_destroy(GTS_OBJECT(s2));
250
gts_bb_tree_destroy(tree1, true);
251
gts_bb_tree_destroy(tree2, true);
252
throw "the intersection of 1 and 2 is not a closed curve\n";
255
s3 = gts_surface_new(gts_surface_class(),
260
gts_surface_inter_boolean(si, s3, GTS_1_OUT_2);
261
gts_surface_inter_boolean(si, s3, GTS_2_OUT_1);
263
else if (Type == 1) {
264
gts_surface_inter_boolean(si, s3, GTS_1_IN_2);
265
gts_surface_inter_boolean(si, s3, GTS_2_IN_1);
267
else if (Type == 2) {
268
gts_surface_inter_boolean(si, s3, GTS_1_OUT_2);
269
gts_surface_inter_boolean(si, s3, GTS_2_IN_1);
270
gts_surface_foreach_face(si->s2, (GtsFunc)gts_triangle_revert, NULL);
271
gts_surface_foreach_face(s2, (GtsFunc)gts_triangle_revert, NULL);
273
else if (Type == 3) {
274
gts_surface_inter_boolean(si, s3, GTS_1_IN_2);
276
else if (Type == 4) {
277
gts_surface_inter_boolean(si, s3, GTS_1_OUT_2);
281
if (check_self_intersection) {
282
GtsSurface* self_intersects;
284
self_intersects = gts_surface_is_self_intersecting(s3);
285
if (self_intersects != NULL) {
289
gts_object_destroy(GTS_OBJECT(self_intersects));
290
gts_object_destroy(GTS_OBJECT(s1));
291
gts_object_destroy(GTS_OBJECT(s2));
292
gts_object_destroy(GTS_OBJECT(s3));
293
gts_object_destroy(GTS_OBJECT(si));
294
gts_bb_tree_destroy(tree1, true);
295
gts_bb_tree_destroy(tree2, true);
296
throw std::runtime_error("the resulting surface is self-intersecting\n");
305
fillMeshFromGTSSurface(pResult, s3);
309
gts_object_destroy(GTS_OBJECT(s1));
310
gts_object_destroy(GTS_OBJECT(s2));
327
static GtsEdge* new_edge(GtsVertex* v1, GtsVertex* v2)
329
GtsSegment* s = gts_vertices_are_connected(v1, v2);
331
return gts_edge_new(gts_edge_class(), v1, v2);
339
GtsSurface* MeshAlgos::createGTSSurface(MeshCore::MeshKernel* Mesh)
341
GtsSurface* Surf = gts_surface_new(gts_surface_class(),
346
unsigned long p1, p2, p3;
347
Base::Vector3f Vertex;
351
GtsVertex** aVertex = (GtsVertex**)malloc(Mesh->CountPoints() * sizeof(GtsVertex*));
352
for (unsigned int PIter = 0; PIter < Mesh->CountPoints(); PIter++) {
353
Vertex = Mesh->GetPoint(PIter);
354
aVertex[PIter] = gts_vertex_new(gts_vertex_class(), Vertex.x, Vertex.y, Vertex.z);
358
for (unsigned int pFIter = 0; pFIter < Mesh->CountFacets(); pFIter++) {
360
Mesh->GetFacetPoints(pFIter, p1, p2, p3);
363
gts_surface_add_face(Surf,
364
gts_face_new(Surf->face_class,
365
new_edge(aVertex[p1], aVertex[p2]),
366
new_edge(aVertex[p2], aVertex[p3]),
367
new_edge(aVertex[p3], aVertex[p1])));
370
Base::Console().Log("GTS [%d faces, %d Points, %d Edges,%s ,%s]\n",
371
gts_surface_face_number(Surf),
372
gts_surface_vertex_number(Surf),
373
gts_surface_edge_number(Surf),
374
gts_surface_is_orientable(Surf) ? "orientable" : "not orientable",
375
gts_surface_is_self_intersecting(Surf) ? "self-intersections"
376
: "no self-intersection");
382
static void onFaces(GtsTriangle* t, std::vector<MeshGeomFacet>* VAry)
384
GtsVertex *mv0, *mv1, *mv2;
386
gts_triangle_vertices(t, &mv0, &mv1, &mv2);
388
VAry->push_back(MeshGeomFacet(Base::Vector3f(mv0->p.x, mv0->p.y, mv0->p.z),
389
Base::Vector3f(mv1->p.x, mv1->p.y, mv1->p.z),
390
Base::Vector3f(mv2->p.x, mv2->p.y, mv2->p.z)));
399
void MeshAlgos::fillMeshFromGTSSurface(MeshCore::MeshKernel* pMesh, GtsSurface* pSurface)
401
std::vector<MeshGeomFacet> VAry;
407
gts_surface_foreach_face(pSurface, (GtsFunc)onFaces, &VAry);
410
gts_object_destroy(GTS_OBJECT(pSurface));
418
#include <BRep_Tool.hxx>
419
#include <GeomAPI_IntCS.hxx>
420
#include <GeomLProp_CLProps.hxx>
421
#include <Geom_Curve.hxx>
422
#include <Geom_Plane.hxx>
424
#include <TopExp_Explorer.hxx>
426
#include <TopoDS_Edge.hxx>
427
#include <TopoDS_Vertex.hxx>
428
#include <TopoDS_Wire.hxx>
430
void MeshAlgos::cutByShape(const TopoDS_Shape& aShape,
431
const MeshCore::MeshKernel* pMesh,
432
MeshCore::MeshKernel* pToolMesh)
437
CurveProjectorWithToolMesh Project(aShape, *pMesh, *pToolMesh);
456
void MeshAlgos::cutByCurve(MeshCore::MeshKernel* pMesh,
457
const std::vector<CurveProjector::FaceSplitEdge>& vSplitEdges)
459
MeshTopoAlgorithm cTopAlg(*pMesh);
461
for (const auto& it : vSplitEdges) {
462
cTopAlg.SplitFacet(it.ulFaceIndex, it.p1, it.p2);
469
bool operator()(const TopoDS_Vertex& rclV1, const TopoDS_Vertex& rclV2) const
471
if (rclV1.IsSame(rclV2) == Standard_True) {
475
gp_XYZ clP1 = BRep_Tool::Pnt(rclV1).XYZ();
476
gp_XYZ clP2 = BRep_Tool::Pnt(rclV2).XYZ();
478
if (fabs(clP1.X() - clP2.X()) < dE) {
479
if (fabs(clP1.Y() - clP2.Y()) < dE) {
480
return clP1.Z() < clP2.Z();
483
return clP1.Y() < clP2.Y();
487
return clP1.X() < clP2.X();
495
void MeshAlgos::LoftOnCurve(MeshCore::MeshKernel& ResultMesh,
496
const TopoDS_Shape& Shape,
497
const std::vector<Base::Vector3f>& poly,
498
const Base::Vector3f& up,
502
Standard_Real fBegin, fEnd;
503
std::vector<MeshGeomFacet> cVAry;
504
std::map<TopoDS_Vertex, std::vector<Base::Vector3f>, _VertexCompare> ConnectMap;
506
for (Ex.Init(Shape, TopAbs_EDGE); Ex.More(); Ex.Next()) {
508
TopoDS_Edge Edge = (TopoDS_Edge&)Ex.Current();
509
TopoDS_Vertex V1, V2;
510
TopExp::Vertices(Edge, V1, V2);
511
bool bBegin = false, bEnd = false;
513
GeomLProp_CLProps prop(BRep_Tool::Curve(Edge, fBegin, fEnd), 1, 0.0000000001);
514
int res = int((fEnd - fBegin) / MaxSize);
521
std::vector<Base::Vector3f> prePoint(poly.size());
522
std::vector<Base::Vector3f> actPoint(poly.size());
525
if (ConnectMap.find(V1) != ConnectMap.end()) {
527
prePoint = ConnectMap[V1];
530
if (ConnectMap.find(V2) != ConnectMap.end()) {
534
for (long i = 0; i < res; i++) {
537
prop.SetParameter(fBegin + ((fEnd - fBegin) * float(i)) / float(res - 1));
538
prop.Tangent(Tangent);
539
Base::Vector3f Tng((float)Tangent.X(), (float)Tangent.Y(), (float)Tangent.Z());
540
Base::Vector3f Ptn((float)prop.Value().X(),
541
(float)prop.Value().Y(),
542
(float)prop.Value().Z());
543
Base::Vector3f Up(up);
547
Base::Vector3f Third(Tng % Up);
552
std::vector<Base::Vector3f>::const_iterator It;
555
for (It = poly.begin(); It != poly.end(); ++It, l++) {
556
actPoint[l] = ((Third * It->x) + (Up * It->y) + (Tng * It->z) + Ptn);
559
if (i == res - 1 && !bEnd) {
561
ConnectMap[V2] = actPoint;
564
if (i == 1 && bBegin) {
566
prePoint = ConnectMap[V1];
569
if (i == 0 && !bBegin) {
571
ConnectMap[V1] = actPoint;
576
for (l = 0; l < actPoint.size(); l++) {
579
if (i == res - 1 && bEnd) {
580
actPoint = ConnectMap[V2];
583
Base::Vector3f p1 = prePoint[l - 1], p2 = actPoint[l - 1], p3 = prePoint[l],
586
cVAry.emplace_back(p1, p2, p3);
587
cVAry.emplace_back(p3, p2, p4);
596
ResultMesh.AddFacets(cVAry);