Skip to content

Commit 212c5ae

Browse files
committed
update example LoadFileWithGeometryExample
1 parent fa8e9b1 commit 212c5ae

File tree

4 files changed

+169
-109
lines changed

4 files changed

+169
-109
lines changed

IfcPlusPlus/src/ifcpp/geometry/ConverterOSG.h

Lines changed: 50 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ class ConverterOSG : public StatusCallback
236236

237237
//#define DEBUG_DRAW_NORMALS
238238

239-
static void drawMeshSet(const shared_ptr<carve::mesh::MeshSet<3> >& meshset, osg::Geode* geode, double crease_angle, double min_triangle_area, bool add_color_array = false)
239+
void drawMeshSet(const shared_ptr<carve::mesh::MeshSet<3> >& meshset, osg::Geode* geode, double crease_angle, double min_triangle_area, bool add_color_array, bool disableBackFaceCulling)
240240
{
241241
if (!meshset)
242242
{
@@ -467,6 +467,12 @@ class ConverterOSG : public StatusCallback
467467
geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, vertices_tri->size()));
468468
geode->addDrawable(geometry);
469469

470+
// disable back face culling for open meshes
471+
if (disableBackFaceCulling)
472+
{
473+
geometry->getOrCreateStateSet()->setAttributeAndModes(m_cull_back_off.get(), osg::StateAttribute::OFF);
474+
}
475+
470476
#ifdef DEBUG_DRAW_NORMALS
471477
osg::ref_ptr<osg::Vec3Array> vertices_normals = new osg::Vec3Array();
472478
for (size_t i = 0; i < vertices_tri->size(); ++i)
@@ -667,7 +673,7 @@ class ConverterOSG : public StatusCallback
667673
}
668674
}
669675

670-
void applyAppearancesToGroup(const std::vector<shared_ptr<AppearanceData> >& vec_product_appearances, osg::Group* grp)
676+
void applyAppearancesToGroup(const std::vector<shared_ptr<AppearanceData> >& vec_product_appearances, osg::Group* grp, float transparencyOverride)
671677
{
672678
for (size_t ii = 0; ii < vec_product_appearances.size(); ++ii)
673679
{
@@ -680,7 +686,7 @@ class ConverterOSG : public StatusCallback
680686
if (appearance->m_apply_to_geometry_type == AppearanceData::GEOM_TYPE_SURFACE || appearance->m_apply_to_geometry_type == AppearanceData::GEOM_TYPE_ANY)
681687
{
682688
osg::ref_ptr<osg::StateSet> item_stateset;
683-
convertToOSGStateSet(appearance, item_stateset);
689+
convertToOSGStateSet(appearance, item_stateset, transparencyOverride);
684690
if (item_stateset)
685691
{
686692
osg::StateSet* existing_item_stateset = grp->getStateSet();
@@ -712,7 +718,7 @@ class ConverterOSG : public StatusCallback
712718
mat_in.m[3][0], mat_in.m[3][1], mat_in.m[3][2], mat_in.m[3][3]);
713719
}
714720

715-
void convertMeshSets(std::vector<shared_ptr<carve::mesh::MeshSet<3> > >& vecMeshSets, osg::Geode* geode, size_t ii_item)
721+
void convertMeshSets(std::vector<shared_ptr<carve::mesh::MeshSet<3> > >& vecMeshSets, osg::Geode* geode, size_t ii_item, bool disableBackfaceCulling)
716722
{
717723
double min_triangle_area = m_geom_settings->getMinTriangleArea();
718724
double eps = m_geom_settings->getEpsilonCoplanarDistance();
@@ -721,15 +727,12 @@ class ConverterOSG : public StatusCallback
721727
{
722728
shared_ptr<carve::mesh::MeshSet<3> >& item_meshset = vecMeshSets[ii];
723729

724-
//static void retriangulateMeshSetSimple(shared_ptr<carve::mesh::MeshSet<3> >&meshset, bool ignoreResultOpenEdges, GeomProcessingParams & params, size_t retryCount);
725-
726730
double epsCoplanarFacesAngle = eps;
727731
double minFaceArea = eps;
728732
bool dumpMeshes = false;
729733
GeomProcessingParams params(eps, epsCoplanarFacesAngle, minFaceArea, dumpMeshes);
730734
MeshOps::retriangulateMeshSetSimple(item_meshset, true, params, 0);
731-
//osg::ref_ptr<osg::Geode> geode = item_group;//new osg::Geode();
732-
drawMeshSet(item_meshset, geode, crease_angle, min_triangle_area);
735+
drawMeshSet(item_meshset, geode, crease_angle, min_triangle_area, false, disableBackfaceCulling);
733736

734737
if (m_render_crease_edges)
735738
{
@@ -748,7 +751,6 @@ class ConverterOSG : public StatusCallback
748751

749752
void convertGeometricItem(const shared_ptr<ItemShapeData>& item_data, shared_ptr<IfcProduct>& ifc_product, size_t ii_representation, size_t ii_item, osg::Group* parentNode, float transparencyOverride)
750753
{
751-
752754
bool includeChildren = false;
753755
if (item_data->hasGeometricRepresentation(includeChildren))
754756
{
@@ -760,29 +762,27 @@ class ConverterOSG : public StatusCallback
760762
product_guid = ifc_product->m_GlobalId->m_value;
761763
}
762764

765+
std::string ifc_entity_type = EntityFactory::getStringForClassID(ifc_product->classID());
763766
std::stringstream strs_product_switch_name;
764-
strs_product_switch_name << product_guid << ":" << EntityFactory::getStringForClassID(ifc_product->classID()) << " group";
767+
strs_product_switch_name << product_guid << ":" << ifc_entity_type << " group";
765768
std::string product_switch_name = strs_product_switch_name.str();
766769

767770
#ifdef _DEBUG
768771
int tag = ifc_product->m_tag;
769-
if (product_guid.compare("3WMG3ehJnBiu4F_L5ltNmO") == 0)
772+
if (product_guid.compare("3WMG3ehJnBiu4F_L5ltNmO") == 0 || ifc_product->classID() == IFC4X3::IFCWINDOW)
770773
{
771774
int wait = 0;
772775
}
773776
#endif
774777

775-
// create shape for open shells
776778
if (item_data->m_meshsets_open.size() > 0)
777779
{
778-
osg::ref_ptr<osg::Geode> geode_open_meshes = new osg::Geode();
779-
convertMeshSets(item_data->m_meshsets_open, geode_open_meshes, ii_item);
780780
// disable back face culling for open meshes
781-
geode_open_meshes->getOrCreateStateSet()->setAttributeAndModes(m_cull_back_off.get(), osg::StateAttribute::OFF);
782-
item_geode->addChild(geode_open_meshes);
781+
convertMeshSets(item_data->m_meshsets_open, item_geode, ii_item, true);
783782
}
784783

785-
convertMeshSets(item_data->m_meshsets, item_geode, ii_item);
784+
// create shape for closed meshes
785+
convertMeshSets(item_data->m_meshsets, item_geode, ii_item, false);
786786

787787
// create shape for points
788788
const std::vector<shared_ptr<carve::input::VertexData> >& vertex_points = item_data->getVertexPoints();
@@ -862,18 +862,12 @@ class ConverterOSG : public StatusCallback
862862
txt->setText(text_str.c_str());
863863
txt->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
864864

865-
osg::ref_ptr<osg::Geode> geode = new osg::Geode();
866-
geode->addDrawable(txt);
867-
//representation_switch->addChild(geode);
865+
osg::ref_ptr<osg::Geode> geodeText = new osg::Geode();
866+
geodeText->addDrawable(txt);
867+
item_geode->addChild(geodeText);
868868
}
869869
}
870870

871-
// apply statesets if there are any
872-
if (item_data->m_vec_item_appearances.size() > 0)
873-
{
874-
applyAppearancesToGroup(item_data->m_vec_item_appearances, item_geode);
875-
}
876-
877871
// If anything has been created, add it to the product group
878872
if (item_geode->getNumChildren() > 0)
879873
{
@@ -884,9 +878,22 @@ class ConverterOSG : public StatusCallback
884878
}
885879
#endif
886880

881+
// apply statesets if there are any
882+
if (item_data->m_vec_item_appearances.size() > 0)
883+
{
884+
applyAppearancesToGroup(item_data->m_vec_item_appearances, item_geode, transparencyOverride);
885+
}
886+
887887
if (transparencyOverride > 0)
888888
{
889-
SceneGraphUtils::setMaterialAlpha(item_geode, transparencyOverride, false);
889+
bool hasTriangles = SceneGraphUtils::hasTrianglesWithMaterial(item_geode);
890+
bool createMaterialIfNotExisting = false;
891+
892+
if (!hasTriangles)
893+
{
894+
createMaterialIfNotExisting = true;
895+
}
896+
SceneGraphUtils::setMaterialAlpha(item_geode, transparencyOverride, createMaterialIfNotExisting );
890897
}
891898

892899
parentNode->addChild(item_geode);
@@ -898,8 +905,6 @@ class ConverterOSG : public StatusCallback
898905
const shared_ptr<ItemShapeData>& child = item_data->m_child_items[i_item];
899906
convertGeometricItem(child, ifc_product, ii_representation, i_item, parentNode, transparencyOverride);
900907
}
901-
902-
903908
}
904909

905910
//\brief method convertProductShapeToOSG: creates geometry objects from an IfcProduct object
@@ -923,8 +928,7 @@ class ConverterOSG : public StatusCallback
923928

924929
product_guid = product_shape->m_entity_guid;
925930
auto it_find = m_map_entity_guid_to_switch.find(product_guid);
926-
927-
if (it_find != m_map_entity_guid_to_switch.end())
931+
if (it_find == m_map_entity_guid_to_switch.end())
928932
{
929933
m_map_entity_guid_to_switch[product_guid] = product_switch;
930934
}
@@ -937,10 +941,9 @@ class ConverterOSG : public StatusCallback
937941
if (!product_shape->m_ifc_object_definition.expired())
938942
{
939943
shared_ptr<IfcObjectDefinition> ifc_object_def(product_shape->m_ifc_object_definition);
940-
shared_ptr<IfcProduct> ifc_product = dynamic_pointer_cast<IfcProduct>(ifc_object_def);
941-
942944
entityType = EntityFactory::getStringForClassID(ifc_object_def->classID());
943-
945+
946+
shared_ptr<IfcProduct> ifc_product = dynamic_pointer_cast<IfcProduct>(ifc_object_def);
944947
if (ifc_product)
945948
{
946949
// enable transparency for certain objects
@@ -976,7 +979,7 @@ class ConverterOSG : public StatusCallback
976979
}
977980

978981
#ifdef _DEBUG
979-
if (product_guid.compare("3WMG3ehJnBiu4F_L5ltNmO") == 0)
982+
if (product_guid.compare("0mmrfTIC96mu8Q5Pb3rKvn") == 0)
980983
{
981984
int wait = 0;
982985
}
@@ -1005,7 +1008,7 @@ class ConverterOSG : public StatusCallback
10051008
// TODO: if no color or material is given, set color 231/219/169 for walls, 140/140/140 for slabs
10061009
if (product_shape->m_vec_product_appearances.size() > 0)
10071010
{
1008-
applyAppearancesToGroup(product_shape->m_vec_product_appearances, product_transform);
1011+
applyAppearancesToGroup(product_shape->m_vec_product_appearances, product_transform, transparencyOverride);
10091012
}
10101013

10111014
++m_numConvertedProducts;
@@ -1162,15 +1165,15 @@ class ConverterOSG : public StatusCallback
11621165
progressValueCallback(0.9, "scenegraph");
11631166
}
11641167

1165-
void convertToOSGStateSet(const shared_ptr<AppearanceData>& appearence, osg::ref_ptr<osg::StateSet>& target_stateset)
1168+
void convertToOSGStateSet(const shared_ptr<AppearanceData>& appearence, osg::ref_ptr<osg::StateSet>& target_stateset, float transparencyOverride)
11661169
{
11671170
if (!appearence)
11681171
{
11691172
return;
11701173
}
1171-
const float shininess = appearence->m_shininess;
1172-
const float transparency = appearence->m_transparency;
1173-
const bool set_transparent = appearence->m_set_transparent;
1174+
float shininess = appearence->m_shininess;
1175+
float transparency = appearence->m_transparency;
1176+
bool set_transparent = appearence->m_set_transparent;
11741177

11751178
const float color_ambient_r = appearence->m_color_ambient.r();
11761179
const float color_ambient_g = appearence->m_color_ambient.g();
@@ -1187,6 +1190,12 @@ class ConverterOSG : public StatusCallback
11871190
const float color_specular_b = appearence->m_color_specular.b();
11881191
const float color_specular_a = appearence->m_color_specular.a();
11891192

1193+
if (transparencyOverride > 0)
1194+
{
1195+
set_transparent = true;
1196+
transparency = transparencyOverride;
1197+
}
1198+
11901199
osg::Vec4f ambientColor(color_ambient_r, color_ambient_g, color_ambient_b, transparency);
11911200
osg::Vec4f diffuseColor(color_diffuse_r, color_diffuse_g, color_diffuse_b, transparency);
11921201
osg::Vec4f specularColor(color_specular_r, color_specular_g, color_specular_b, transparency);
@@ -1202,7 +1211,7 @@ class ConverterOSG : public StatusCallback
12021211
target_stateset = new osg::StateSet();
12031212
target_stateset->setAttribute(mat, osg::StateAttribute::ON);
12041213

1205-
if (appearence->m_set_transparent)
1214+
if (set_transparent)
12061215
{
12071216
mat->setTransparency(osg::Material::FRONT, transparency);
12081217
target_stateset->setMode(GL_BLEND, osg::StateAttribute::ON);

IfcPlusPlus/src/ifcpp/geometry/SceneGraphUtils.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,48 @@ namespace SceneGraphUtils
517517
}
518518
}
519519
}
520+
521+
inline bool hasTrianglesWithMaterial(osg::Node* node)
522+
{
523+
osg::ref_ptr<osg::Material> mat;
524+
osg::StateSet* stateset = node->getStateSet();
525+
if (stateset)
526+
{
527+
mat = dynamic_cast<osg::Material*>(stateset->getAttribute(osg::StateAttribute::MATERIAL));
528+
}
529+
530+
osg::Geometry* geom = dynamic_cast<osg::Geometry*>(node);
531+
if (geom)
532+
{
533+
for (unsigned int ii = 0; ii < geom->getNumPrimitiveSets(); ++ii)
534+
{
535+
osg::PrimitiveSet* prim = geom->getPrimitiveSet(ii);
536+
537+
if (prim->getMode() == osg::PrimitiveSet::TRIANGLES || prim->getMode() == osg::PrimitiveSet::QUADS)
538+
{
539+
if (mat)
540+
{
541+
return true;
542+
}
543+
}
544+
}
545+
}
546+
547+
osg::Group* group = dynamic_cast<osg::Group*>(node);
548+
if (group)
549+
{
550+
for (unsigned int ii = 0; ii < group->getNumChildren(); ++ii)
551+
{
552+
osg::Node* child_node = group->getChild(ii);
553+
if (hasTrianglesWithMaterial(child_node))
554+
{
555+
return true;
556+
}
557+
}
558+
}
559+
return false;
560+
}
561+
520562
inline void setMaterialAlpha( osg::Node* node, float alpha, bool create_material_if_not_existing )
521563
{
522564
osg::StateSet* stateset = node->getOrCreateStateSet();
@@ -541,6 +583,7 @@ namespace SceneGraphUtils
541583
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
542584
}
543585
}
586+
544587
osg::Group* group = dynamic_cast<osg::Group*>( node );
545588
if( group )
546589
{
@@ -551,6 +594,7 @@ namespace SceneGraphUtils
551594
}
552595
}
553596
}
597+
554598
inline void removeChildren( osg::Group* group )
555599
{
556600
if( group )

0 commit comments

Comments
 (0)