Skip to content

Commit 4e8f2fd

Browse files
committed
fix bug in spline computation
1 parent cd32769 commit 4e8f2fd

14 files changed

+236
-148
lines changed

IfcPlusPlus/src/ifcpp/geometry/CurveConverter.h

+19-33
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,7 @@ class CurveConverter : public StatusCallback
220220
if( bspline_curve )
221221
{
222222
m_spline_converter->convertBSplineCurve(bspline_curve, target_vec, segment_start_points);
223-
224223
// TODO: handle trim points
225-
226224
return;
227225
}
228226

@@ -844,7 +842,7 @@ class CurveConverter : public StatusCallback
844842
bool p1_success = PointConverter::convertIfcVertex(edge_end, p1, length_factor);
845843

846844

847-
//std::cout << "IfcEdgeLoop: IfcPointOnCurve, IfcPointOnSurface not implemented" << std::endl;
845+
848846

849847
bool simpleStraightEdge = false;
850848
if( simpleStraightEdge )
@@ -854,14 +852,9 @@ class CurveConverter : public StatusCallback
854852
return;
855853
}
856854

857-
858-
// TODO: try use EdgeStart and EdgeEnd as trimming points
859-
860855
const shared_ptr<IfcOrientedEdge> orientedEdge = dynamic_pointer_cast<IfcOrientedEdge>(edge);
861856
if( orientedEdge )
862857
{
863-
//#3517327= IFCORIENTEDEDGE(*,*,#3517018,.T.);
864-
865858
//shared_ptr<IfcEdge> m_EdgeElement;
866859
//shared_ptr<IfcBoolean> m_Orientation;
867860
bool orientedEdgeOrientation = orientedEdge->m_Orientation->m_value;
@@ -878,8 +871,6 @@ class CurveConverter : public StatusCallback
878871
const shared_ptr<IfcSubedge> subEdge = dynamic_pointer_cast<IfcSubedge>(edge);
879872
if( subEdge )
880873
{
881-
//shared_ptr<IfcEdge> m_ParentEdge;
882-
883874
if( subEdge->m_ParentEdge )
884875
{
885876
std::vector<vec3> loopPointsParentEdge;
@@ -889,7 +880,6 @@ class CurveConverter : public StatusCallback
889880
}
890881
}
891882

892-
893883
const shared_ptr<IfcEdgeCurve> edgeCurve = dynamic_pointer_cast<IfcEdgeCurve>(edge);
894884
if( edgeCurve )
895885
{
@@ -901,11 +891,6 @@ class CurveConverter : public StatusCallback
901891
edgeSameSense = edgeCurve->m_SameSense->m_value;
902892
}
903893

904-
//#3517014= IFCBSPLINECURVEWITHKNOTS(3,(#3517000,#3517000,#3517006,#3517008,#3517010,#3517012,#3517003),.UNSPECIFIED.,.F.,.U.,(4,1,1,1,4),(0.,0.166666666666667,0.333333333333333,0.666666666666667,1.),.UNSPECIFIED.);
905-
//#3517018= IFCEDGECURVE(#3517002,#3517005,#3517014,.T.);
906-
//#3517327= IFCORIENTEDEDGE(*,*,#3517018,.T.);
907-
//#3517329= IFCEDGELOOP((#3517326,#3517327,#3517328));
908-
909894
if( !edgeSameSense )
910895
{
911896
vec3 temp = p0;
@@ -915,12 +900,12 @@ class CurveConverter : public StatusCallback
915900

916901
std::vector<vec3> curvePoints;
917902
std::vector<vec3> segmentStartPoints;
918-
const shared_ptr<IfcCurve> edgeCurveCurve = edgeCurve->m_EdgeGeometry;
903+
const shared_ptr<IfcCurve> edgeCurveGeometry = edgeCurve->m_EdgeGeometry;
919904
bool senseAgreement = true;
920905

921-
if( edgeCurveCurve )
906+
if( edgeCurveGeometry )
922907
{
923-
shared_ptr<IfcTrimmedCurve> trimmedCurve = dynamic_pointer_cast<IfcTrimmedCurve>(edgeCurveCurve);
908+
shared_ptr<IfcTrimmedCurve> trimmedCurve = dynamic_pointer_cast<IfcTrimmedCurve>(edgeCurveGeometry);
924909
if( trimmedCurve )
925910
{
926911
const shared_ptr<IfcCurve> basisCurve = trimmedCurve->m_BasisCurve;
@@ -931,15 +916,15 @@ class CurveConverter : public StatusCallback
931916
std::vector<shared_ptr<IfcTrimmingSelect> > curve_trim2_vec;
932917

933918
shared_ptr<IfcCartesianPoint> trim1(new IfcCartesianPoint());
934-
trim1->m_Coordinates[0] = p0.x;
935-
trim1->m_Coordinates[1] = p0.y;
936-
trim1->m_Coordinates[2] = p0.z;
919+
trim1->m_Coordinates[0] = p0.x / length_factor; // in convertIfcCurve, the trim point will be multiplied with length_factor
920+
trim1->m_Coordinates[1] = p0.y / length_factor;
921+
trim1->m_Coordinates[2] = p0.z / length_factor;
937922
curve_trim1_vec.push_back(trim1);
938923

939924
shared_ptr<IfcCartesianPoint> trim2(new IfcCartesianPoint());
940-
trim2->m_Coordinates[0] = p1.x;
941-
trim2->m_Coordinates[1] = p1.y;
942-
trim2->m_Coordinates[2] = p1.z;
925+
trim2->m_Coordinates[0] = p1.x / length_factor;
926+
trim2->m_Coordinates[1] = p1.y / length_factor;
927+
trim2->m_Coordinates[2] = p1.z / length_factor;
943928
curve_trim2_vec.push_back(trim2);
944929
convertIfcCurve(basisCurve, curvePoints, segmentStartPoints, curve_trim1_vec, curve_trim2_vec, senseAgreement);
945930
}
@@ -948,7 +933,7 @@ class CurveConverter : public StatusCallback
948933
{
949934
std::vector<shared_ptr<IfcTrimmingSelect> > curve_trim1_vec;
950935
std::vector<shared_ptr<IfcTrimmingSelect> > curve_trim2_vec;
951-
convertIfcCurve(edgeCurveCurve, curvePoints, segmentStartPoints, curve_trim1_vec, curve_trim2_vec, senseAgreement);
936+
convertIfcCurve(edgeCurveGeometry, curvePoints, segmentStartPoints, curve_trim1_vec, curve_trim2_vec, senseAgreement);
952937
}
953938
}
954939
else
@@ -977,7 +962,7 @@ class CurveConverter : public StatusCallback
977962
glm::vec4 color(0.5, 0.5, 0.5, 1);
978963
if( dist0 > EPS_M6 || dist1 > EPS_M6 )
979964
{
980-
GeomDebugDump::dumpPolyline(curvePoints, color, false);
965+
//GeomDebugDump::dumpPolyline(curvePoints, color, false);
981966
}
982967

983968
if( dist0 > EPS_M6 )
@@ -986,7 +971,7 @@ class CurveConverter : public StatusCallback
986971
//std::cout << std::endl << "check EdgeStart IfcEdgeCurve, dist0 = " << dist0 << ", tag: " << tag << std::endl;
987972

988973
std::vector<vec3> segmentStartEndPoints = { p0, p1 };
989-
GeomDebugDump::dumpPolyline(segmentStartEndPoints, color, true);
974+
//GeomDebugDump::dumpPolyline(segmentStartEndPoints, color, true);
990975
}
991976

992977
if( false )
@@ -1098,22 +1083,18 @@ class CurveConverter : public StatusCallback
10981083

10991084
for( const shared_ptr<IfcOrientedEdge>& oriented_edge : edge_loop->m_EdgeList )
11001085
{
1101-
// shared_ptr<IfcVertex> m_EdgeStart;
1102-
// shared_ptr<IfcVertex> m_EdgeEnd;
1103-
11041086
// IfcOrientedEdge -----------------------------------------------------------
11051087
// attributes:
11061088
//shared_ptr<IfcEdge> m_EdgeElement;
11071089
//shared_ptr<IfcBoolean> m_Orientation;
11081090

1109-
shared_ptr<IfcEdge> edge = oriented_edge->m_EdgeElement;
1110-
11111091
bool orientation = true;
11121092
if( oriented_edge->m_Orientation )
11131093
{
11141094
orientation = oriented_edge->m_Orientation->m_value;
11151095
}
11161096

1097+
shared_ptr<IfcEdge> edge = oriented_edge->m_EdgeElement;
11171098
std::vector<vec3> edge_points;
11181099
convertIfcEdge(edge, edge_points, length_factor);
11191100

@@ -1125,6 +1106,11 @@ class CurveConverter : public StatusCallback
11251106
{
11261107
std::copy(edge_points.rbegin(), edge_points.rend(), std::back_inserter(loop_points));
11271108
}
1109+
1110+
#ifdef _DEBUG
1111+
//glm::vec4 color(0.5, 0.5, 0.5, 1);
1112+
//GeomDebugDump::dumpPolyline(loop_points, color, false);
1113+
#endif
11281114
}
11291115

11301116
GeomUtils::removeDuplicates(loop_points);

IfcPlusPlus/src/ifcpp/geometry/FaceConverter.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ class FaceConverter : public StatusCallback
348348
if( advancedFace )
349349
{
350350
int tag = advancedFace->m_tag;
351-
if( tag == 3518020 )
351+
if( tag == 1261069 )
352352
{
353353
std::cout << "IfcAdvancedFace, tag=" << tag << std::endl;
354354
}
@@ -420,9 +420,9 @@ class FaceConverter : public StatusCallback
420420
MeshUtils::createTriangulated3DFace( face_loops, poly_cache, params );
421421

422422
#ifdef _DEBUG
423-
if( ifc_face->m_tag == 46832 )
423+
if( ifc_face->m_tag == 1261069 )
424424
{
425-
params.debugDump = true;
425+
//params.debugDump = true;
426426
}
427427

428428
//if( ifc_face->m_tag == 2529 )
@@ -439,7 +439,7 @@ class FaceConverter : public StatusCallback
439439
GeomDebugDump::dumpPolyline(loop, color, false);
440440
}
441441

442-
if( ii == 34 )
442+
//if( ii == 34 )
443443
{
444444
PolyInputCache3D poly_cache_dump(CARVE_EPSILON);
445445
MeshUtils::createTriangulated3DFace(face_loops, poly_cache_dump, params);

IfcPlusPlus/src/ifcpp/geometry/GeometryConverter.h

+48-5
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,10 @@ class GeometryConverter : public StatusCallback
6262
vec3 m_siteOffset;
6363
double m_recent_progress = 0;
6464
std::map<int, std::vector<shared_ptr<StatusCallback::Message> > > m_messages;
65+
6566
#ifdef _OPENMP
6667
Mutex m_writelock_messages;
68+
Mutex m_writelock_item_cache;
6769
#endif
6870

6971
public:
@@ -92,7 +94,11 @@ class GeometryConverter : public StatusCallback
9294
m_ifc_model->setMessageTarget( this );
9395
m_representation_converter->setMessageTarget( this );
9496
}
95-
virtual ~GeometryConverter() {}
97+
virtual ~GeometryConverter()
98+
{
99+
m_callback_object_geometry_converted = nullptr;
100+
m_callback_func_geometry_converted = nullptr;
101+
}
96102

97103
void setGeometryCallbackFunction( void* obj_ptr, void (*func)(void*, shared_ptr<ProductShapeData> t) )
98104
{
@@ -798,8 +804,7 @@ class GeometryConverter : public StatusCallback
798804
if( m_callback_object_geometry_converted )
799805
{
800806
#ifdef _OPENMP
801-
// Note: this lock protects accesses only for this instance. If several StatusCallback (or derived) objects are bound to the same callback function, a lock is necessary there.
802-
ScopedLock lock( m_writelock );
807+
//ScopedLock lock( m_writelock_geom_callback );
803808
#endif
804809
m_callback_func_geometry_converted( m_callback_object_geometry_converted, product_geom_input_data );
805810
}
@@ -808,7 +813,7 @@ class GeometryConverter : public StatusCallback
808813

809814
// progress callback
810815
double progress = (double)i / (double)num_object_definitions;
811-
if( progress - m_recent_progress > 0.02 )
816+
if( progress - m_recent_progress > 0.01 )
812817
{
813818

814819
#ifdef _OPENMP
@@ -1056,9 +1061,47 @@ class GeometryConverter : public StatusCallback
10561061
}
10571062
}
10581063
}
1064+
1065+
// check for existing meshes
1066+
// TODO: make sure that the meshes are not changed after here, for example with boolean operations
1067+
bool enableCaching = false;
1068+
if( enableCaching )
1069+
{
1070+
bool equalItemFound = false;
1071+
1072+
for( auto it : m_product_shape_data )
1073+
{
1074+
const shared_ptr<ProductShapeData>& existingProductShape = it.second;
1075+
if( !existingProductShape )
1076+
{
1077+
continue;
1078+
}
1079+
for( auto rep : existingProductShape->m_vec_representations )
1080+
{
1081+
for( auto item : rep->m_vec_item_data )
1082+
{
1083+
//bool itemIsEqual = isEqual(item, geom_item_data);
1084+
//if( itemIsEqual )
1085+
{
1086+
//representation_data->m_vec_item_data.push_back(existingItem);
1087+
equalItemFound = true;
1088+
}
1089+
}
1090+
}
1091+
}
1092+
if( !equalItemFound )
1093+
{
1094+
// representation_data->m_vec_item_data.push_back(geom_item_data);
1095+
//#ifdef _OPENMP
1096+
// ScopedLock lock( m_writelock_item_cache );
1097+
//#endif
1098+
// m_map_item_data_cache.push_back(geom_item_data);
1099+
}
1100+
}
1101+
10591102
if( m_clear_memory_immedeately )
10601103
{
1061-
vec_representations.clear();
1104+
ifc_product->m_Representation.reset();
10621105
}
10631106
}
10641107

IfcPlusPlus/src/ifcpp/geometry/GeometryInputData.h

+66
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,7 @@ class ItemShapeData
681681
weak_ptr<RepresentationData> m_parent_representation; // Pointer to representation object that this item belongs to
682682
shared_ptr<IFC4X3::IfcRepresentationItem> m_ifc_item;
683683
std::vector<shared_ptr<carve::input::VertexData> > m_vertex_points;
684+
std::set<int> m_usedInRepresentations;
684685

685686
public:
686687
bool isEmpty()
@@ -1588,7 +1589,72 @@ class ProductShapeData
15881589
}
15891590
};
15901591

1592+
inline bool isEqual(const shared_ptr<carve::mesh::MeshSet<3> >& existingMesh, const shared_ptr<carve::mesh::MeshSet<3> >& checkMesh)
1593+
{
1594+
if( existingMesh->meshes.size() != checkMesh->meshes.size() ) { return false; }
1595+
if( existingMesh->vertex_storage.size() != checkMesh->vertex_storage.size() ) { return false; }
1596+
1597+
for( size_t ii = 0; ii < existingMesh->meshes.size(); ++ii )
1598+
{
1599+
const carve::mesh::Mesh<3>* mesh1 = existingMesh->meshes[ii];
1600+
const carve::mesh::Mesh<3>* mesh2 = checkMesh->meshes[ii];
1601+
if( mesh1->closed_edges.size() != mesh2->closed_edges.size() ) { return false; }
1602+
if( mesh1->open_edges.size() != mesh2->open_edges.size() ) { return false; }
1603+
if( mesh1->faces.size() != mesh2->faces.size() ) { return false; }
1604+
1605+
for( size_t jj = 0; jj < mesh1->faces.size(); ++jj )
1606+
{
1607+
const carve::mesh::Face<3>* face1 = mesh1->faces[jj];
1608+
const carve::mesh::Face<3>* face2 = mesh2->faces[jj];
1609+
if( face1->n_edges != face2->n_edges ) { return false; }
1610+
1611+
const carve::mesh::Edge<3>* edge1 = face1->edge;
1612+
const carve::mesh::Edge<3>* edge2 = face2->edge;
1613+
1614+
for( size_t kk = 0; kk < face1->n_edges; ++kk )
1615+
{
1616+
const carve::mesh::Vertex<3>* vertex1 = edge1->vert;
1617+
const carve::mesh::Vertex<3>* vertex2 = edge2->vert;
1618+
vec3 delt = vertex1->v - vertex2->v;
1619+
if( delt.x > 0.0001 ) { return false; }
1620+
if( delt.x < -0.0001 ) { return false; }
1621+
if( delt.y > 0.0001 ) { return false; }
1622+
if( delt.y < -0.0001 ) { return false; }
1623+
if( delt.z > 0.0001 ) { return false; }
1624+
if( delt.z < -0.0001 ) { return false; }
1625+
edge1 = edge1->next;
1626+
edge2 = edge2->next;
1627+
}
1628+
}
1629+
}
1630+
return true;
1631+
}
15911632

1633+
inline bool isEqual(const shared_ptr<ItemShapeData>& existingItem, const shared_ptr<ItemShapeData>& checkItem)
1634+
{
1635+
if( existingItem->m_meshsets.size() != checkItem->m_meshsets.size() ) { return false; }
1636+
if( existingItem->m_meshsets_open.size() != checkItem->m_meshsets_open.size() ) { return false; }
1637+
1638+
for( size_t ii = 0; ii < existingItem->m_meshsets.size(); ++ii )
1639+
{
1640+
shared_ptr<carve::mesh::MeshSet<3> >& meshset1 = existingItem->m_meshsets[ii];
1641+
shared_ptr<carve::mesh::MeshSet<3> >& meshset2 = checkItem->m_meshsets[ii];
1642+
if( !isEqual(meshset1, meshset2) )
1643+
{
1644+
return false;
1645+
}
1646+
}
1647+
for( size_t ii = 0; ii < existingItem->m_meshsets_open.size(); ++ii )
1648+
{
1649+
shared_ptr<carve::mesh::MeshSet<3> >& meshset1 = existingItem->m_meshsets_open[ii];
1650+
shared_ptr<carve::mesh::MeshSet<3> >& meshset2 = checkItem->m_meshsets_open[ii];
1651+
if( !isEqual(meshset1, meshset2) )
1652+
{
1653+
return false;
1654+
}
1655+
}
1656+
return true;
1657+
}
15921658

15931659
static carve::geom::aabb<3> computeBoundingBoxLocalCoords( const shared_ptr<ProductShapeData>& productData, bool includeChildren )
15941660
{

IfcPlusPlus/src/ifcpp/geometry/GeometrySettings.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ class GeometrySettings
117117
int m_num_vertices_per_circle = 14;
118118
int m_num_vertices_per_circle_default = 14;
119119
int m_min_num_vertices_per_arc = 5;
120-
int m_num_vertices_per_control_point = 4;
121-
int m_num_vertices_per_control_point_default = 4;
120+
int m_num_vertices_per_control_point = 1;
121+
int m_num_vertices_per_control_point_default = 1;
122122
bool m_show_text_literals = false;
123123
bool m_ignore_profile_radius = false;
124124
bool m_handle_styled_items = true;

0 commit comments

Comments
 (0)