Parcourir la source

Merge pull request #1208 from terziman/master

Added parameters to IFC importer to control tessellation
Kim Kulling il y a 8 ans
Parent
commit
1c525a9365

+ 2 - 2
code/IFCGeometry.cpp

@@ -258,7 +258,7 @@ void ProcessRevolvedAreaSolid(const IfcRevolvedAreaSolid& solid, TempMesh& resul
         return;
     }
 
-    const unsigned int cnt_segments = std::max(2u,static_cast<unsigned int>(16 * std::fabs(max_angle)/AI_MATH_HALF_PI_F));
+    const unsigned int cnt_segments = std::max(2u,static_cast<unsigned int>(conv.settings.cylindricalTessellation * std::fabs(max_angle)/AI_MATH_HALF_PI_F));
     const IfcFloat delta = max_angle/cnt_segments;
 
     has_area = has_area && std::fabs(max_angle) < AI_MATH_TWO_PI_F*0.99;
@@ -327,7 +327,7 @@ void ProcessSweptDiskSolid(const IfcSweptDiskSolid solid, TempMesh& result, Conv
         return;
     }
 
-    const unsigned int cnt_segments = 16;
+    const unsigned int cnt_segments = conv.settings.cylindricalTessellation;
     const IfcFloat deltaAngle = AI_MATH_TWO_PI/cnt_segments;
 
     const size_t samples = curve->EstimateSampleCount(solid.StartParam,solid.EndParam);

+ 3 - 4
code/IFCLoader.cpp

@@ -153,11 +153,10 @@ const aiImporterDesc* IFCImporter::GetInfo () const
 void IFCImporter::SetupProperties(const Importer* pImp)
 {
     settings.skipSpaceRepresentations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_IFC_SKIP_SPACE_REPRESENTATIONS,true);
-    settings.skipCurveRepresentations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_IFC_SKIP_CURVE_REPRESENTATIONS,true);
     settings.useCustomTriangulation = pImp->GetPropertyBool(AI_CONFIG_IMPORT_IFC_CUSTOM_TRIANGULATION,true);
-
-    settings.conicSamplingAngle = 10.f;
-    settings.skipAnnotations = true;
+    settings.conicSamplingAngle = std::min(std::max(pImp->GetPropertyFloat(AI_CONFIG_IMPORT_IFC_SMOOTHING_ANGLE, AI_IMPORT_IFC_DEFAULT_SMOOTHING_ANGLE), 5.0f), 120.0f);
+	settings.cylindricalTessellation = std::min(std::max(pImp->GetPropertyInteger(AI_CONFIG_IMPORT_IFC_CYLINDRICAL_TESSELLATION, AI_IMPORT_IFC_DEFAULT_CYLINDRICAL_TESSELLATION), 3), 180);
+	settings.skipAnnotations = true;
 }
 
 

+ 2 - 2
code/IFCLoader.h

@@ -107,18 +107,18 @@ public:
     {
         Settings()
             : skipSpaceRepresentations()
-            , skipCurveRepresentations()
             , useCustomTriangulation()
             , skipAnnotations()
             , conicSamplingAngle(10.f)
+			, cylindricalTessellation(32)
         {}
 
 
         bool skipSpaceRepresentations;
-        bool skipCurveRepresentations;
         bool useCustomTriangulation;
         bool skipAnnotations;
         float conicSamplingAngle;
+		int cylindricalTessellation;
     };
 
 

+ 14 - 6
code/IFCOpenings.cpp

@@ -901,13 +901,21 @@ size_t CloseWindows(ContourVector& contours,
             curmesh.verts.reserve(curmesh.verts.size() + (*it).contour.size() * 4);
             curmesh.vertcnt.reserve(curmesh.vertcnt.size() + (*it).contour.size());
 
+			bool reverseCountourFaces = false;
+
             // compare base poly normal and contour normal to detect if we need to reverse the face winding
-            IfcVector3 basePolyNormal = TempMesh::ComputePolygonNormal( curmesh.verts.data(), curmesh.vertcnt.front());
-            std::vector<IfcVector3> worldSpaceContourVtx( it->contour.size());
-            for( size_t a = 0; a < it->contour.size(); ++a )
-                worldSpaceContourVtx[a] = minv * IfcVector3( it->contour[a].x, it->contour[a].y, 0.0);
-            IfcVector3 contourNormal = TempMesh::ComputePolygonNormal( worldSpaceContourVtx.data(), worldSpaceContourVtx.size());
-            bool reverseCountourFaces = (contourNormal * basePolyNormal) > 0.0;
+			if(curmesh.vertcnt.size() > 0) {
+				IfcVector3 basePolyNormal = TempMesh::ComputePolygonNormal(curmesh.verts.data(), curmesh.vertcnt.front());
+				
+				std::vector<IfcVector3> worldSpaceContourVtx(it->contour.size());
+				
+				for(size_t a = 0; a < it->contour.size(); ++a)
+					worldSpaceContourVtx[a] = minv * IfcVector3(it->contour[a].x, it->contour[a].y, 0.0);
+				
+				IfcVector3 contourNormal = TempMesh::ComputePolygonNormal(worldSpaceContourVtx.data(), worldSpaceContourVtx.size());
+				
+				reverseCountourFaces = (contourNormal * basePolyNormal) > 0.0;
+			}
 
             // XXX this algorithm is really a bit inefficient - both in terms
             // of constant factor and of asymptotic runtime.

+ 2 - 2
code/IFCProfile.cpp

@@ -101,7 +101,7 @@ void ProcessOpenProfile(const IfcArbitraryOpenProfileDef& def, TempMesh& meshout
 }
 
 // ------------------------------------------------------------------------------------------------
-void ProcessParametrizedProfile(const IfcParameterizedProfileDef& def, TempMesh& meshout, ConversionData& /*conv*/)
+void ProcessParametrizedProfile(const IfcParameterizedProfileDef& def, TempMesh& meshout, ConversionData& conv)
 {
     if(const IfcRectangleProfileDef* const cprofile = def.ToPtr<IfcRectangleProfileDef>()) {
         const IfcFloat x = cprofile->XDim*0.5f, y = cprofile->YDim*0.5f;
@@ -117,7 +117,7 @@ void ProcessParametrizedProfile(const IfcParameterizedProfileDef& def, TempMesh&
         if(def.ToPtr<IfcCircleHollowProfileDef>()) {
             // TODO
         }
-        const size_t segments = 32;
+        const size_t segments = conv.settings.cylindricalTessellation;
         const IfcFloat delta = AI_MATH_TWO_PI_F/segments, radius = circle->Radius;
 
         meshout.verts.reserve(segments);

+ 36 - 15
include/assimp/config.h.in

@@ -844,14 +844,6 @@ enum aiComponent
 #define AI_CONFIG_IMPORT_OGRE_TEXTURETYPE_FROM_FILENAME \
     "IMPORT_OGRE_TEXTURETYPE_FROM_FILENAME"
 
-/** @brief Specifies whether the IFC loader skips over IfcSpace elements.
- *
- * IfcSpace elements (and their geometric representations) are used to
- * represent, well, free space in a building storey.<br>
- * Property type: Bool. Default value: true.
- */
-#define AI_CONFIG_IMPORT_IFC_SKIP_SPACE_REPRESENTATIONS "IMPORT_IFC_SKIP_SPACE_REPRESENTATIONS"
-
  /** @brief Specifies whether the Android JNI asset extraction is supported.
   *
   * Turn on this option if you want to manage assets in native
@@ -860,17 +852,14 @@ enum aiComponent
   */
  #define AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT "AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT"
 
-
 // ---------------------------------------------------------------------------
-/** @brief Specifies whether the IFC loader skips over
- *    shape representations of type 'Curve2D'.
+/** @brief Specifies whether the IFC loader skips over IfcSpace elements.
  *
- * A lot of files contain both a faceted mesh representation and a outline
- * with a presentation type of 'Curve2D'. Currently Assimp doesn't convert those,
- * so turning this option off just clutters the log with errors.<br>
+ * IfcSpace elements (and their geometric representations) are used to
+ * represent, well, free space in a building storey.<br>
  * Property type: Bool. Default value: true.
  */
-#define AI_CONFIG_IMPORT_IFC_SKIP_CURVE_REPRESENTATIONS "IMPORT_IFC_SKIP_CURVE_REPRESENTATIONS"
+#define AI_CONFIG_IMPORT_IFC_SKIP_SPACE_REPRESENTATIONS "IMPORT_IFC_SKIP_SPACE_REPRESENTATIONS"
 
 // ---------------------------------------------------------------------------
 /** @brief Specifies whether the IFC loader will use its own, custom triangulation
@@ -887,6 +876,38 @@ enum aiComponent
  */
 #define AI_CONFIG_IMPORT_IFC_CUSTOM_TRIANGULATION "IMPORT_IFC_CUSTOM_TRIANGULATION"
 
+// ---------------------------------------------------------------------------
+/** @brief  Set the tessellation conic angle for IFC smoothing curves.
+ *
+ * This is used by the IFC importer to determine the tessellation parameter
+ * for smoothing curves.
+ * @note The default value is AI_IMPORT_IFC_DEFAULT_SMOOTHING_ANGLE and the
+ * accepted values are in range [5.0, 120.0].
+ * Property type: Float.
+ */
+#define AI_CONFIG_IMPORT_IFC_SMOOTHING_ANGLE "IMPORT_IFC_SMOOTHING_ANGLE"
+
+// default value for AI_CONFIG_IMPORT_IFC_SMOOTHING_ANGLE
+#if (!defined AI_IMPORT_IFC_DEFAULT_SMOOTHING_ANGLE)
+#   define AI_IMPORT_IFC_DEFAULT_SMOOTHING_ANGLE 10.0f
+#endif
+
+// ---------------------------------------------------------------------------
+/** @brief  Set the tessellation for IFC cylindrical shapes.
+ *
+ * This is used by the IFC importer to determine the tessellation parameter
+ * for cylindrical shapes, i.e. the number of segments used to aproximate a circle.
+ * @note The default value is AI_IMPORT_IFC_DEFAULT_CYLINDRICAL_TESSELLATION and the
+ * accepted values are in range [3, 180].
+ * Property type: Integer.
+ */
+#define AI_CONFIG_IMPORT_IFC_CYLINDRICAL_TESSELLATION "IMPORT_IFC_CYLINDRICAL_TESSELLATION"
+
+// default value for AI_CONFIG_IMPORT_IFC_CYLINDRICAL_TESSELLATION
+#if (!defined AI_IMPORT_IFC_DEFAULT_CYLINDRICAL_TESSELLATION)
+#   define AI_IMPORT_IFC_DEFAULT_CYLINDRICAL_TESSELLATION 32
+#endif
+
 // ---------------------------------------------------------------------------
 /** @brief Specifies whether the Collada loader will ignore the provided up direction.
  *

+ 23 - 0
include/assimp/metadata.h

@@ -198,6 +198,29 @@ struct aiMetadata {
         return data;
     }
 
+	template<typename T>
+	inline void Add(const std::string& key, const T& value)
+	{
+		aiString* new_keys = new aiString[mNumProperties + 1];
+		aiMetadataEntry* new_values = new aiMetadataEntry[mNumProperties + 1];
+
+		for(unsigned int i = 0; i < mNumProperties; ++i)
+		{
+			new_keys[i] = mKeys[i];
+			new_values[i] = mValues[i];
+		}
+
+		delete mKeys;
+		delete mValues;
+
+		mKeys = new_keys;
+		mValues = new_values;
+
+		mNumProperties++;
+
+		Set(mNumProperties - 1, key, value);
+	}
+
     template<typename T>
     inline 
     bool Set( unsigned index, const std::string& key, const T& value ) {