Skip to content

Commit b5ef1ec

Browse files
committed
bugfix: fix crash at mesh creation ( disable normal creation )
1 parent bda3952 commit b5ef1ec

File tree

3 files changed

+52
-15
lines changed

3 files changed

+52
-15
lines changed

src/ifcmax/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
# check for 3ds Max SDK
2121
set(valid_max_years 2027 2026 2025 2024 2023 2022 2021 2020 2019 2018 2017)
2222

23+
# might be dangerous to use tools 143 for all max versions
2324
set(max_toolset_versions_143 "2017" "2018" "2019" "2020" "2021" "2022" "2023" "2024" "2025" "2026" "2027" )
25+
# set(max_toolset_versions_143 "2025" "2026" "2027" )
2426
# set(max_toolset_versions_142 "2022" "2023" "2024" )
2527
# set(max_toolset_versions_141 "2020" "2021" )
2628
# set(max_toolset_versions_140 "2017" "2018" "2019" )

src/ifcmax/IfcMax.cpp

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,6 @@ int IFCImp::DoImport(const TCHAR *file_name, ImpInterface *impitfc, Interface *i
295295

296296

297297
settings.get<ifcopenshell::geometry::settings::ReorientShells>().value = true; // should be true
298-
settings.get<ifcopenshell::geometry::settings::WeldVertices>().value = true; // should be true
299298
settings.get<ifcopenshell::geometry::settings::UnifyShapes>().value = true; // should be true
300299
settings.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = false; // should be false to get a pivot with correct coordinates
301300
//settings.get<ifcopenshell::geometry::settings::UseMaterialNames>().value = false;
@@ -309,8 +308,11 @@ int IFCImp::DoImport(const TCHAR *file_name, ImpInterface *impitfc, Interface *i
309308
// ATTENTION: breaks hierarchy positioning when active ( "site-local-placement" )
310309
settings.get<ifcopenshell::geometry::settings::SiteLocalPlacement>().value = false; // should be FALSE
311310

311+
// when vertex welding is enabled, normals calculation is internally disabled ( see OpenCascadeConversionResult.cpp:239 )
312+
settings.get<ifcopenshell::geometry::settings::WeldVertices>().value = true; // should be true
312313

313314
settings.get<ifcopenshell::geometry::settings::DontEmitNormals>().value = false;
315+
settings.get<ifcopenshell::geometry::settings::GenerateUvs>().value = false;
314316

315317

316318
settings.get<ifcopenshell::geometry::settings::CircleSegments>().value = 32; // should be 32
@@ -342,8 +344,8 @@ int IFCImp::DoImport(const TCHAR *file_name, ImpInterface *impitfc, Interface *i
342344
auto annotations = file.instances_by_type("IfcAnnotation");
343345
auto solids = file.instances_by_type("IfcSolidModel");
344346

345-
// previous "opencascade"
346-
//IfcGeom::Iterator iterator( "hybrid-cgal-simple-opencascade", settings, &file);
347+
// cgal kernels produce std::vector incompatiblities
348+
//auto kernel = ifcopenshell::geometry::kernels::construct(&file, "hybrid-cgal-simple-opencascade", settings);
347349

348350
auto kernel = ifcopenshell::geometry::kernels::construct(&file, "opencascade", settings);
349351
IfcGeom::Iterator iterator( std::move( kernel), settings, &file);
@@ -406,7 +408,10 @@ int IFCImp::DoImport(const TCHAR *file_name, ImpInterface *impitfc, Interface *i
406408

407409
RefResult refSuccess = REF_INVALID;
408410

409-
refSuccess = impNode->Reference(BuildMesh(triElement));
411+
auto mesh = BuildMesh(triElement);
412+
413+
if ( mesh != nullptr)
414+
refSuccess = impNode->Reference(mesh);
410415

411416
if (refSuccess != REF_SUCCEED) {
412417
LogToListener(_M("Error creating importer reference for imported element #%d.\n"), element->id());
@@ -488,34 +493,47 @@ void IFCImp::BuildFullName( const IfcUtil::IfcBaseEntity& entity, MSTR& long_nam
488493
TriObject* IFCImp::BuildMesh(const IfcGeom::TriangulationElement* element) {
489494
TriObject* tri = CreateNewTriObject();
490495

491-
const auto& verts = element->geometry().verts();
496+
const IfcGeom::Representation::Triangulation& ios_mesh = element->geometry();
497+
498+
const auto& verts = ios_mesh.verts();
492499
const int numVerts = (int)verts.size() / 3;
493500

501+
//const auto& normals = ios_mesh.normals();
502+
// const int numNormals = (int)normals.size() / 3;
503+
504+
// const auto& uvs = ios_mesh.uvs();
505+
// const int numUVs = (int)uvs.size() / 3;
506+
507+
494508
tri->mesh.setNumVerts(numVerts);
495509
for (int i = 0; i < numVerts; i++) {
496510
tri->mesh.setVert(i, Point3ByIndex(verts, i));
511+
//if( i < numNormals ) {
512+
// tri->mesh.setNormal(i, Point3ByIndex(normals, i));
513+
// }
497514
}
498515

499-
bool needs_default = std::find(element->geometry().material_ids().begin(), element->geometry().material_ids().end(), -1) != element->geometry().material_ids().end();
516+
bool needs_default = std::find(ios_mesh.material_ids().begin(), ios_mesh.material_ids().end(), -1) != ios_mesh.material_ids().end();
500517

501518
typedef std::pair<int, int> edge_t;
502519

503520
std::set<edge_t> face_boundaries;
504-
for (std::vector<int>::const_iterator it = element->geometry().edges().begin(); it != element->geometry().edges().end();) {
521+
for (std::vector<int>::const_iterator it = ios_mesh.edges().begin(); it != ios_mesh.edges().end();) {
505522
const int v1 = *it++;
506523
const int v2 = *it++;
507524

508525
const edge_t e((std::min)(v1, v2), (std::max)(v1, v2));
509526
face_boundaries.insert(e);
510527
}
511528

512-
const auto& faces = element->geometry().faces();
529+
const auto& faces = ios_mesh.faces();
530+
513531
const int numFaces = (int)faces.size() / 3;
514532

515533
tri->mesh.setNumFaces(numFaces);
516534

517535
for (int i = 0; i < numFaces; i++) {
518-
const int v1 = faces[3 * i + 0];
536+
const int v1 = faces[3 * i + 0];
519537
const int v2 = faces[3 * i + 1];
520538
const int v3 = faces[3 * i + 2];
521539

@@ -530,24 +548,41 @@ TriObject* IFCImp::BuildMesh(const IfcGeom::TriangulationElement* element) {
530548
tri->mesh.faces[i].setVerts(v1, v2, v3);
531549
tri->mesh.faces[i].setEdgeVisFlags(b1, b2, b3);
532550

533-
MtlID mtlid = (MtlID)element->geometry().material_ids()[i];
551+
MtlID mtlid = (MtlID)ios_mesh.material_ids()[i];
534552
if (needs_default) {
535553
mtlid++;
536554
}
537555
tri->mesh.faces[i].setMatID(mtlid);
538556
}
539557

540-
tri->mesh.buildNormals();
558+
bool valid = tri->CheckObjectIntegrity();
559+
560+
if (!valid) {
561+
return nullptr;
562+
}
563+
564+
// apply simple box mapping
565+
#if MAX_VERSION_MAJOR < 22
566+
// in 3ds Max 2017-2019 SDK, Matrix3::Identity was declared in matrix3.h, but did'nt actually exist in the lib ....
567+
Matrix3 ident(TRUE);
568+
tri->mesh.ApplyUVWMap(MAP_ACAD_BOX, 1, 1, 1, 0, 0, 0, 0, ident);
569+
#else
570+
tri->mesh.ApplyUVWMap(MAP_ACAD_BOX, 1, 1, 1, 0, 0, 0, 0, Matrix3::Identity);
571+
#endif
572+
573+
// this one tends to crash, so we skip it for the time being
574+
// tri->mesh.buildNormals();
575+
541576
// Either use this or undefine the FACESETS_AS_COMPOUND option in IfcGeom.h to have
542577
// properly oriented normals. Using only the line below will result in a consistent
543578
// orientation of normals across shells, but not always oriented towards the
544579
// outside.
545580
// tri->mesh.UnifyNormals(false);
546-
tri->mesh.BuildStripsAndEdges();
581+
582+
tri->mesh.BuildStripsAndEdges();
547583
tri->mesh.InvalidateTopologyCache();
548584
tri->mesh.InvalidateGeomCache();
549-
550-
return tri;
585+
return tri;
551586
}
552587

553588
inline Point3 IFCImp::Point3ByIndex(const std::vector<double>& verts, int index) {

src/ifcmax/IfcMax.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class IFCImp : public SceneImport {
3939
BOOL VerifyCancel();
4040

4141
private:
42-
inline Point3 IFCImp::Point3ByIndex(const std::vector<double>& verts, int index);
42+
inline Point3 Point3ByIndex(const std::vector<double>& verts, int index);
4343
void BuildFullName(const IfcUtil::IfcBaseEntity& entity, MSTR& long_name);
4444
TriObject* BuildMesh(const IfcGeom::TriangulationElement* triElement);
4545
};

0 commit comments

Comments
 (0)