@@ -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
488493TriObject* 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
553588inline Point3 IFCImp::Point3ByIndex (const std::vector<double >& verts, int index) {
0 commit comments