mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-13 19:07:57 +00:00
Last minute refactoring
This commit is contained in:
@@ -185,13 +185,10 @@ class IfcStore:
|
||||
os.makedirs(os.path.dirname(cache_path), exist_ok=True)
|
||||
IfcStore.cache_path = cache_path
|
||||
cache_path = Path(IfcStore.cache_path)
|
||||
cache_settings = ifcopenshell.geom.settings()
|
||||
serializer_settings = ifcopenshell.geom.serializer_settings()
|
||||
settings = ifcopenshell.geom.settings()
|
||||
cache_preexists = cache_path.exists()
|
||||
try:
|
||||
IfcStore.cache = ifcopenshell.geom.serializers.hdf5(
|
||||
IfcStore.cache_path, cache_settings, serializer_settings
|
||||
)
|
||||
IfcStore.cache = ifcopenshell.geom.serializers.hdf5(IfcStore.cache_path, settings)
|
||||
if cache_preexists:
|
||||
print(f"Successfully loaded existing cache: {cache_path.name}.")
|
||||
else:
|
||||
@@ -206,9 +203,7 @@ class IfcStore:
|
||||
|
||||
os.remove(IfcStore.cache_path)
|
||||
try:
|
||||
IfcStore.cache = ifcopenshell.geom.serializers.hdf5(
|
||||
IfcStore.cache_path, cache_settings, serializer_settings
|
||||
)
|
||||
IfcStore.cache = ifcopenshell.geom.serializers.hdf5(IfcStore.cache_path, settings)
|
||||
print("New cache was created.")
|
||||
except Exception as e:
|
||||
print(f"Failed to create a cache: {str(e)}.")
|
||||
|
||||
@@ -1406,31 +1406,28 @@ class CreateDrawing(bpy.types.Operator):
|
||||
# Backwards compatibility with older ifcopenshell builds that don't expose these keys.
|
||||
pass
|
||||
self.svg_buffer = ifcopenshell.geom.serializers.buffer()
|
||||
self.serialiser_settings = ifcopenshell.geom.serializer_settings()
|
||||
self.serialiser_settings.set("svg-without-storeys", True)
|
||||
self.serialiser_settings.set("svg-write-poly", True)
|
||||
self.serialiser_settings.set("svg-poly", True)
|
||||
self.svg_settings.set("svg-without-storeys", True)
|
||||
self.svg_settings.set("svg-write-poly", True)
|
||||
self.svg_settings.set("svg-poly", True)
|
||||
# Objects with more than these edges are rendered as wireframe instead of HLR for optimisation
|
||||
self.serialiser_settings.set("profile-threshold", 10000)
|
||||
self.serialiser_settings.set("svg-xmlns", True)
|
||||
self.serialiser_settings.set("svg-project", True)
|
||||
self.serialiser_settings.set("auto-elevation", False)
|
||||
self.serialiser_settings.set("auto-section", False)
|
||||
self.serialiser_settings.set("print-space-names", False)
|
||||
self.serialiser_settings.set("print-space-areas", False)
|
||||
self.serialiser_settings.set("door-arcs", False)
|
||||
self.serialiser_settings.set("svg-no-css", True)
|
||||
self.serialiser_settings.set("elevation-ref-guid", self.camera_element.GlobalId)
|
||||
self.serialiser_settings.set("scale", str(self.scale))
|
||||
self.serialiser_settings.set("svg-subtract-before", "always")
|
||||
self.serialiser_settings.set("svg-prefilter", True) # See #3359
|
||||
self.serialiser_settings.set("svg-unify-inputs", True)
|
||||
self.serialiser_settings.set("svg-segment-projection", True)
|
||||
self.svg_settings.set("profile-threshold", 10000)
|
||||
self.svg_settings.set("svg-xmlns", True)
|
||||
self.svg_settings.set("svg-project", True)
|
||||
self.svg_settings.set("auto-elevation", False)
|
||||
self.svg_settings.set("auto-section", False)
|
||||
self.svg_settings.set("print-space-names", False)
|
||||
self.svg_settings.set("print-space-areas", False)
|
||||
self.svg_settings.set("door-arcs", False)
|
||||
self.svg_settings.set("svg-no-css", True)
|
||||
self.svg_settings.set("elevation-ref-guid", self.camera_element.GlobalId)
|
||||
self.svg_settings.set("scale", str(self.scale))
|
||||
self.svg_settings.set("svg-subtract-before", "always")
|
||||
self.svg_settings.set("svg-prefilter", True) # See #3359
|
||||
self.svg_settings.set("svg-unify-inputs", True)
|
||||
self.svg_settings.set("svg-segment-projection", True)
|
||||
if target_view == "REFLECTED_PLAN_VIEW":
|
||||
self.serialiser_settings.set("svg-mirror-y", True)
|
||||
self.serialiser = ifcopenshell.geom.serializers.svg(
|
||||
self.svg_buffer, self.svg_settings, self.serialiser_settings
|
||||
)
|
||||
self.svg_settings.set("svg-mirror-y", True)
|
||||
self.serialiser = ifcopenshell.geom.serializers.svg(self.svg_buffer, self.svg_settings)
|
||||
# tree = ifcopenshell.geom.tree()
|
||||
# This instructs the tree to explode BReps into faces and return
|
||||
# the style of the face when running tree.select_ray()
|
||||
|
||||
@@ -72,11 +72,10 @@ class ExportOBJ(bpy.types.Operator):
|
||||
# Conversion from IFC to OBJ
|
||||
# Settings for obj
|
||||
settings = ifcopenshell.geom.settings()
|
||||
serializer_settings = ifcopenshell.geom.serializer_settings()
|
||||
|
||||
settings.set("dimensionality", ifcopenshell.ifcopenshell_wrapper.SURFACES_AND_SOLIDS)
|
||||
settings.set("apply-default-materials", True)
|
||||
serializer_settings.set("use-element-guids", True)
|
||||
settings.set("use-element-guids", True)
|
||||
settings.set("use-world-coords", True)
|
||||
|
||||
ifc_file: ifcopenshell.file
|
||||
@@ -90,7 +89,7 @@ class ExportOBJ(bpy.types.Operator):
|
||||
obj_file_path = os.path.join(output_dir, "model.obj")
|
||||
mtl_file_path = os.path.join(output_dir, "model.mtl")
|
||||
|
||||
serialiser = ifcopenshell.geom.serializers.obj(obj_file_path, mtl_file_path, settings, serializer_settings)
|
||||
serialiser = ifcopenshell.geom.serializers.obj(obj_file_path, mtl_file_path, settings)
|
||||
serialiser.setFile(ifc_file)
|
||||
serialiser.setUnitNameAndMagnitude("METER", 1.0)
|
||||
serialiser.writeHeader()
|
||||
|
||||
@@ -163,32 +163,29 @@ class Drawer:
|
||||
|
||||
# self.svg_settings.set_deflection_tolerance(0.0001)
|
||||
self.svg_buffer = ifcopenshell.geom.serializers.buffer()
|
||||
self.serialiser_settings = ifcopenshell.geom.serializer_settings()
|
||||
self.serialiser_settings.set("svg-without-storeys", True)
|
||||
self.serialiser_settings.set("svg-write-poly", True)
|
||||
self.serialiser_settings.set("svg-poly", True)
|
||||
self.svg_settings.set("svg-without-storeys", True)
|
||||
self.svg_settings.set("svg-write-poly", True)
|
||||
self.svg_settings.set("svg-poly", True)
|
||||
# Objects with more than these edges are rendered as wireframe instead of HLR for optimisation
|
||||
self.serialiser_settings.set("profile-threshold", 10000)
|
||||
self.serialiser_settings.set("svg-xmlns", True)
|
||||
self.serialiser_settings.set("svg-project", True)
|
||||
self.serialiser_settings.set("auto-elevation", False)
|
||||
self.serialiser_settings.set("auto-section", False)
|
||||
self.serialiser_settings.set("print-space-names", False)
|
||||
self.serialiser_settings.set("print-space-areas", False)
|
||||
self.serialiser_settings.set("door-arcs", False)
|
||||
self.serialiser_settings.set("svg-no-css", True)
|
||||
self.serialiser_settings.set("elevation-ref-guid", self.camera_element.GlobalId)
|
||||
self.serialiser_settings.set("scale", "1/50")
|
||||
self.serialiser_settings.set("svg-subtract-before", "always")
|
||||
self.serialiser_settings.set("svg-prefilter", True) # See #3359
|
||||
# self.serialiser_settings.set("svg-prefilter", False) # See #3359
|
||||
self.serialiser_settings.set("svg-unify-inputs", True)
|
||||
self.serialiser_settings.set("svg-segment-projection", True)
|
||||
self.svg_settings.set("profile-threshold", 10000)
|
||||
self.svg_settings.set("svg-xmlns", True)
|
||||
self.svg_settings.set("svg-project", True)
|
||||
self.svg_settings.set("auto-elevation", False)
|
||||
self.svg_settings.set("auto-section", False)
|
||||
self.svg_settings.set("print-space-names", False)
|
||||
self.svg_settings.set("print-space-areas", False)
|
||||
self.svg_settings.set("door-arcs", False)
|
||||
self.svg_settings.set("svg-no-css", True)
|
||||
self.svg_settings.set("elevation-ref-guid", self.camera_element.GlobalId)
|
||||
self.svg_settings.set("scale", "1/50")
|
||||
self.svg_settings.set("svg-subtract-before", "always")
|
||||
self.svg_settings.set("svg-prefilter", True) # See #3359
|
||||
# self.svg_settings.set("svg-prefilter", False) # See #3359
|
||||
self.svg_settings.set("svg-unify-inputs", True)
|
||||
self.svg_settings.set("svg-segment-projection", True)
|
||||
if target_view == "REFLECTED_PLAN_VIEW":
|
||||
self.serialiser_settings.set("svg-mirror-y", True)
|
||||
self.serialiser = ifcopenshell.geom.serializers.svg(
|
||||
self.svg_buffer, self.svg_settings, self.serialiser_settings
|
||||
)
|
||||
self.svg_settings.set("svg-mirror-y", True)
|
||||
self.serialiser = ifcopenshell.geom.serializers.svg(self.svg_buffer, self.svg_settings)
|
||||
self.serialiser.setFile(ifc)
|
||||
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ std::optional<BasicElementInfo> ElementRegistry::findBasicElementInfo(uint32_t o
|
||||
return it->second;
|
||||
}
|
||||
|
||||
std::optional<express::Base> ElementRegistry::findEntity(uint32_t object_id) const {
|
||||
std::optional<express::base> ElementRegistry::findEntity(uint32_t object_id) const {
|
||||
if (!loader_) return std::nullopt;
|
||||
|
||||
auto info = findBasicElementInfo(object_id);
|
||||
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
void removeModel(uint32_t session_model_id);
|
||||
std::vector<BasicElementInfo> basicElementInfoForModel(uint32_t session_model_id) const;
|
||||
std::optional<BasicElementInfo> findBasicElementInfo(uint32_t object_id) const;
|
||||
std::optional<express::Base> findEntity(uint32_t object_id) const;
|
||||
std::optional<express::base> findEntity(uint32_t object_id) const;
|
||||
|
||||
private:
|
||||
void onSidecarElementsReady(uint32_t session_model_id,
|
||||
|
||||
@@ -44,7 +44,7 @@ Main components
|
||||
code.
|
||||
|
||||
``GeometryStreamer``
|
||||
Runs ``IfcGeom::Iterator`` on a worker thread for raw IFC loads. It emits a
|
||||
Runs ``ifcopenshell::geom::iterator`` on a worker thread for raw IFC loads. It emits a
|
||||
``StreamedMesh`` once for each unique representation mesh and a
|
||||
``StreamedInstance`` for each placed occurrence.
|
||||
|
||||
|
||||
@@ -685,7 +685,7 @@ void convertIfcToDatabase(SessionState& session, QWidget& host) {
|
||||
throw ifcopenshell::exception("RDB serializer does not support streaming from an input filename");
|
||||
}
|
||||
|
||||
boost::shared_ptr<Serializer> serializer = registry.create("rdb", context);
|
||||
boost::shared_ptr<serializer> serializer = registry.create("rdb", context);
|
||||
serializer->finalize();
|
||||
} catch (const std::exception& e) {
|
||||
*error_message = QString::fromUtf8(e.what());
|
||||
@@ -791,7 +791,7 @@ void exportGeometryDatabase(SessionState& session, QWidget& host) {
|
||||
throw ifcopenshell::exception("RDB serializer does not support streaming from an input filename");
|
||||
}
|
||||
|
||||
boost::shared_ptr<Serializer> serializer = registry.create("rdb", context);
|
||||
boost::shared_ptr<serializer> serializer = registry.create("rdb", context);
|
||||
serializer->finalize();
|
||||
serializer.reset();
|
||||
|
||||
|
||||
@@ -82,9 +82,9 @@ std::string enumString(const attribute_value& av) {
|
||||
return std::string(enumeration.value() ? enumeration.value() : "");
|
||||
}
|
||||
|
||||
QString formatNamedUnit(const express::Base& unit) {
|
||||
QString formatNamedUnit(const express::base& unit) {
|
||||
if (!unit) return "—";
|
||||
auto entity = unit.as<express::Entity>();
|
||||
auto entity = unit.as<express::entity>();
|
||||
if (unit.declaration().is("IfcSIUnit")) {
|
||||
const std::string prefix = enumString(entity.get("Prefix"));
|
||||
const std::string name = enumString(entity.get("Name"));
|
||||
|
||||
@@ -109,7 +109,7 @@ void PropertiesPanelView::refresh(uint32_t object_id) {
|
||||
state.entity = {"No item selected", ""};
|
||||
|
||||
auto entity = registry ? registry->findEntity(object_id)
|
||||
: std::optional<express::Base>{};
|
||||
: std::optional<express::base>{};
|
||||
if (entity) {
|
||||
state.entity.entity_class = QString::fromStdString(entity->declaration().name());
|
||||
if (auto predefined_type = get_predefined_type(*entity)) {
|
||||
@@ -121,16 +121,16 @@ void PropertiesPanelView::refresh(uint32_t object_id) {
|
||||
}
|
||||
// Relationships: the construction type and the spatial container, shown
|
||||
// by name (falling back to the entity class when unnamed).
|
||||
auto display_name = [](const express::Base& related) -> QString {
|
||||
auto display_name = [](const express::base& related) -> QString {
|
||||
if (auto name = get_string_attribute(related, "Name"); name && !name->empty()) {
|
||||
return QString::fromStdString(*name);
|
||||
}
|
||||
return QString::fromStdString(related.declaration().name());
|
||||
};
|
||||
if (express::Base type = get_type(*entity)) {
|
||||
if (express::base type = get_type(*entity)) {
|
||||
state.relationships.append({"Type", display_name(type)});
|
||||
}
|
||||
if (express::Base container = get_container(*entity)) {
|
||||
if (express::base container = get_container(*entity)) {
|
||||
state.relationships.append({"Container", display_name(container)});
|
||||
}
|
||||
// Property sets (Pset_*) and quantity sets (Qto_* / BaseQuantities),
|
||||
|
||||
@@ -60,7 +60,7 @@ TreeNode* findNodeRecursive(QList<TreeNode>& nodes, const NodePath& path, int de
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ItemKind kindOf(const express::Base& element) {
|
||||
ItemKind kindOf(const express::base& element) {
|
||||
const auto& declaration = element.declaration();
|
||||
if (declaration.is("IfcSite")) return ItemKind::Site;
|
||||
if (declaration.is("IfcBuilding")) return ItemKind::Building;
|
||||
@@ -68,14 +68,14 @@ ItemKind kindOf(const express::Base& element) {
|
||||
return ItemKind::Space; // IfcSpace, IfcSpatialZone, …
|
||||
}
|
||||
|
||||
QString displayName(const express::Base& element) {
|
||||
QString displayName(const express::base& element) {
|
||||
if (auto name = get_string_attribute(element, "Name"); name && !name->empty()) {
|
||||
return QString::fromStdString(*name);
|
||||
}
|
||||
return QString::fromStdString(element.declaration().name());
|
||||
}
|
||||
|
||||
TreeNode buildNode(const express::Base& element) {
|
||||
TreeNode buildNode(const express::base& element) {
|
||||
TreeNode node;
|
||||
node.name = displayName(element);
|
||||
node.kind = kindOf(element);
|
||||
|
||||
@@ -101,7 +101,7 @@ int main() {
|
||||
// IfcFacetedBRep. If it would not be a polyhedron, serialise() can only be successful when linked
|
||||
// to the IFC4 model and with `advanced` set to `true` which introduces IfcAdvancedFace. It would
|
||||
// return `0` otherwise.
|
||||
auto building_shape = IfcGeom::serialise(file, building_shell, false).as<IfcSchema::IfcProductDefinitionShape>();
|
||||
auto building_shape = ifcopenshell::geom::serialise(file, building_shell, false).as<IfcSchema::IfcProductDefinitionShape>();
|
||||
|
||||
file.add_entity(building_shape);
|
||||
auto building_representations = building_shape.Representations();
|
||||
@@ -117,9 +117,9 @@ int main() {
|
||||
TopoDS_Shape shape;
|
||||
createGroundShape(shape);
|
||||
|
||||
auto ground_representation = IfcGeom::serialise(file, shape, true);
|
||||
auto ground_representation = ifcopenshell::geom::serialise(file, shape, true);
|
||||
if (!ground_representation) {
|
||||
ground_representation = IfcGeom::tesselate(file, shape, 100.);
|
||||
ground_representation = ifcopenshell::geom::tesselate(file, shape, 100.);
|
||||
}
|
||||
file.getSingle<IfcSchema::IfcSite>().setRepresentation(ground_representation.as<IfcSchema::IfcProductDefinitionShape>());
|
||||
|
||||
@@ -134,10 +134,10 @@ int main() {
|
||||
// Note that IFC lacks elementary surfaces that STEP does have, such as spherical_surface.
|
||||
// BRepBuilderAPI_NurbsConvert can be used to serialize such surfaces as nurbs surfaces.
|
||||
TopoDS_Shape sphere = BRepPrimAPI_MakeSphere(gp_Pnt(), 1000.).Shape();
|
||||
IfcSchema::IfcProductDefinitionShape* sphere_representation = IfcGeom::serialise(sphere, true);
|
||||
IfcSchema::IfcProductDefinitionShape* sphere_representation = ifcopenshell::geom::serialise(sphere, true);
|
||||
if (S(IfcSchema::Identifier) == "IFC4") {
|
||||
sphere = BRepBuilderAPI_NurbsConvert(sphere, true).Shape();
|
||||
sphere_representation = IfcGeom::serialise(sphere, true);
|
||||
sphere_representation = ifcopenshell::geom::serialise(sphere, true);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
@@ -301,7 +301,7 @@ int main() {
|
||||
// will be tessellated using the deflection specified.
|
||||
TopoDS_Shape shape;
|
||||
createGroundShape(shape);
|
||||
auto ground_representation = IfcGeom::tesselate(file, shape, 100.).as<IfcSchema::IfcProductDefinitionShape>();
|
||||
auto ground_representation = ifcopenshell::geom::tesselate(file, shape, 100.).as<IfcSchema::IfcProductDefinitionShape>();
|
||||
file.getSingle<IfcSchema::IfcSite>().setRepresentation(ground_representation);
|
||||
|
||||
GProp_GProps prop;
|
||||
|
||||
@@ -194,7 +194,7 @@ void get_psets_s(element_properties& props, const typename Schema::IfcObjectDefi
|
||||
}
|
||||
}
|
||||
|
||||
element_properties get_psets(const express::Base& inst) {
|
||||
element_properties get_psets(const express::base& inst) {
|
||||
element_properties props;
|
||||
if (auto object_definition = inst.as<IfcSchema::IfcObjectDefinition>()) {
|
||||
get_psets_s<IfcSchema>(props, object_definition);
|
||||
|
||||
+15
-15
@@ -41,7 +41,7 @@ struct is_ifc4_or_higher : std::false_type {};
|
||||
template <typename Schema>
|
||||
struct is_ifc4_or_higher<Schema, std::void_t<typename Schema::IfcMaterialDefinition>> : std::true_type {};
|
||||
|
||||
std::string schema_name(const express::Base& instance) {
|
||||
std::string schema_name(const express::base& instance) {
|
||||
return instance.declaration().schema()->name();
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ std::optional<std::string> format_scalar(const attribute_value& value) {
|
||||
// ifcopenshell.util.element.get_type: the construction type of an occurrence
|
||||
// (get_type(type_element) == type_element).
|
||||
template <typename Schema>
|
||||
express::Base get_type_s(const express::Base& element) {
|
||||
express::base get_type_s(const express::base& element) {
|
||||
if (element.template as<typename Schema::IfcTypeObject>()) {
|
||||
return element;
|
||||
}
|
||||
@@ -111,9 +111,9 @@ express::Base get_type_s(const express::Base& element) {
|
||||
}
|
||||
|
||||
template <typename Schema>
|
||||
std::optional<std::string> get_predefined_type_s(const express::Base& element) {
|
||||
std::optional<std::string> get_predefined_type_s(const express::base& element) {
|
||||
// Prefer the associated type element's predefined type.
|
||||
if (const express::Base type = get_type_s<Schema>(element)) {
|
||||
if (const express::base type = get_type_s<Schema>(element)) {
|
||||
std::optional<std::string> predefined_type = get_string_attribute(type, "PredefinedType");
|
||||
if (!predefined_type || *predefined_type == "USERDEFINED") {
|
||||
// ElementType (IfcElementType) or ProcessType (IfcTypeProcess) — the
|
||||
@@ -140,7 +140,7 @@ std::optional<std::string> get_predefined_type_s(const express::Base& element) {
|
||||
// ifcopenshell.util.element.get_aggregate: the aggregate parent, via the
|
||||
// Decomposes inverse (IfcRelAggregates.RelatingObject).
|
||||
template <typename Schema>
|
||||
express::Base get_aggregate_s(const express::Base& element) {
|
||||
express::base get_aggregate_s(const express::base& element) {
|
||||
const auto object = element.template as<typename Schema::IfcObjectDefinition>();
|
||||
if (!object) {
|
||||
return {};
|
||||
@@ -162,8 +162,8 @@ express::Base get_aggregate_s(const express::Base& element) {
|
||||
// The spatial-structure children aggregated under this element (IsDecomposedBy →
|
||||
// RelatedObjects, filtered to spatial elements).
|
||||
template <typename Schema>
|
||||
std::vector<express::Base> get_spatial_children_s(const express::Base& element) {
|
||||
std::vector<express::Base> children;
|
||||
std::vector<express::base> get_spatial_children_s(const express::base& element) {
|
||||
std::vector<express::base> children;
|
||||
const auto object = element.template as<typename Schema::IfcObjectDefinition>();
|
||||
if (!object) {
|
||||
return children;
|
||||
@@ -182,14 +182,14 @@ std::vector<express::Base> get_spatial_children_s(const express::Base& element)
|
||||
// ifc_class): the directly containing spatial element, or the container of the
|
||||
// aggregate parent for an aggregated part.
|
||||
template <typename Schema>
|
||||
express::Base get_container_s(const express::Base& element) {
|
||||
express::base get_container_s(const express::base& element) {
|
||||
if (const auto product = element.template as<typename Schema::IfcElement>()) {
|
||||
const auto relationships = product.ContainedInStructure();
|
||||
if (!relationships.empty()) {
|
||||
return relationships.front().RelatingStructure();
|
||||
}
|
||||
}
|
||||
if (const express::Base aggregate = get_aggregate_s<Schema>(element)) {
|
||||
if (const express::base aggregate = get_aggregate_s<Schema>(element)) {
|
||||
return get_container_s<Schema>(aggregate);
|
||||
}
|
||||
return {};
|
||||
@@ -197,7 +197,7 @@ express::Base get_container_s(const express::Base& element) {
|
||||
|
||||
} // namespace
|
||||
|
||||
std::optional<std::string> get_predefined_type(const express::Base& element) {
|
||||
std::optional<std::string> get_predefined_type(const express::base& element) {
|
||||
if (!element) {
|
||||
return std::nullopt;
|
||||
}
|
||||
@@ -211,7 +211,7 @@ std::optional<std::string> get_predefined_type(const express::Base& element) {
|
||||
unsupported_schema(name);
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> get_scalar_attributes(const express::Base& element) {
|
||||
std::vector<std::pair<std::string, std::string>> get_scalar_attributes(const express::base& element) {
|
||||
std::vector<std::pair<std::string, std::string>> result;
|
||||
if (!element) {
|
||||
return result;
|
||||
@@ -230,7 +230,7 @@ std::vector<std::pair<std::string, std::string>> get_scalar_attributes(const exp
|
||||
return result;
|
||||
}
|
||||
|
||||
express::Base get_type(const express::Base& element) {
|
||||
express::base get_type(const express::base& element) {
|
||||
if (!element) {
|
||||
return {};
|
||||
}
|
||||
@@ -244,7 +244,7 @@ express::Base get_type(const express::Base& element) {
|
||||
unsupported_schema(name);
|
||||
}
|
||||
|
||||
express::Base get_container(const express::Base& element) {
|
||||
express::base get_container(const express::base& element) {
|
||||
if (!element) {
|
||||
return {};
|
||||
}
|
||||
@@ -258,7 +258,7 @@ express::Base get_container(const express::Base& element) {
|
||||
unsupported_schema(name);
|
||||
}
|
||||
|
||||
std::vector<express::Base> get_spatial_children(const express::Base& element) {
|
||||
std::vector<express::base> get_spatial_children(const express::base& element) {
|
||||
if (!element) {
|
||||
return {};
|
||||
}
|
||||
@@ -275,7 +275,7 @@ std::vector<express::Base> get_spatial_children(const express::Base& element) {
|
||||
// getattr(element, name) for a string- or enum-valued attribute. Reads by name,
|
||||
// so it works uniformly across the various subtypes that carry a given
|
||||
// attribute (PredefinedType, Name, ...).
|
||||
std::optional<std::string> get_string_attribute(const express::Base& element,
|
||||
std::optional<std::string> get_string_attribute(const express::base& element,
|
||||
const std::string& name) {
|
||||
if (!element) {
|
||||
return std::nullopt;
|
||||
|
||||
@@ -35,35 +35,35 @@
|
||||
// type of the associated type element (via IsTypedBy / IsDefinedBy) first.
|
||||
// std::nullopt when there is no such attribute (e.g. the element is not an
|
||||
// IfcObject, or a geometry-only proxy with no live IFC data).
|
||||
std::optional<std::string> get_predefined_type(const express::Base& element);
|
||||
std::optional<std::string> get_predefined_type(const express::base& element);
|
||||
|
||||
// Mirrors ifcopenshell.util.element.get_type: the construction type element of
|
||||
// an occurrence (via IsTypedBy on IFC4+, IsDefinedBy on IFC2X3). A type element
|
||||
// returns itself. Empty express::Base when the element is untyped.
|
||||
express::Base get_type(const express::Base& element);
|
||||
// returns itself. Empty express::base when the element is untyped.
|
||||
express::base get_type(const express::base& element);
|
||||
|
||||
// Mirrors ifcopenshell.util.element.get_container (indirect, no ifc_class
|
||||
// filter): the spatial element that contains this element — the directly
|
||||
// containing spatial structure, or, for an aggregated part, the container of its
|
||||
// aggregate parent. Empty when uncontained. (The nest / filled-void /
|
||||
// voided-element branches of the Python original are not ported.)
|
||||
express::Base get_container(const express::Base& element);
|
||||
express::base get_container(const express::base& element);
|
||||
|
||||
// Safely read a string- or enum-valued attribute by name (Python's getattr).
|
||||
// std::nullopt when the attribute is absent for this entity's type or IFC null.
|
||||
std::optional<std::string> get_string_attribute(const express::Base& element,
|
||||
std::optional<std::string> get_string_attribute(const express::base& element,
|
||||
const std::string& name);
|
||||
|
||||
// The spatial-structure elements aggregated directly under `element` (its
|
||||
// IsDecomposedBy → RelatedObjects, filtered to spatial elements). Used to walk
|
||||
// the IfcProject → IfcSite → IfcBuilding → IfcBuildingStorey → IfcSpace tree.
|
||||
std::vector<express::Base> get_spatial_children(const express::Base& element);
|
||||
std::vector<express::base> get_spatial_children(const express::base& element);
|
||||
|
||||
// The element's direct EXPRESS attributes that have a primitive scalar value
|
||||
// (string / enum / integer / real / boolean / logical), as (name, formatted
|
||||
// value) pairs in declaration order. Attributes that are entity references,
|
||||
// aggregates / lists, or unset (IFC null) are omitted — so the caller gets a
|
||||
// flat, display-ready view with no nested objects.
|
||||
std::vector<std::pair<std::string, std::string>> get_scalar_attributes(const express::Base& element);
|
||||
std::vector<std::pair<std::string, std::string>> get_scalar_attributes(const express::base& element);
|
||||
|
||||
#endif // ELEMENT_H
|
||||
|
||||
@@ -83,7 +83,7 @@ double numeric_property(const property_map& properties,
|
||||
return fallback;
|
||||
}
|
||||
|
||||
double selected_number(const express::Base& selected, double fallback) {
|
||||
double selected_number(const express::base& selected, double fallback) {
|
||||
if (!selected) {
|
||||
return fallback;
|
||||
}
|
||||
@@ -184,7 +184,7 @@ template <typename Schema>
|
||||
std::optional<Eigen::Matrix4d> get_wcs_s(ifcopenshell::file* ifc_file) {
|
||||
const auto contexts =
|
||||
ifc_file->template instances_by_type_excl_subtypes<typename Schema::IfcGeometricRepresentationContext>();
|
||||
express::Base wcs;
|
||||
express::base wcs;
|
||||
for (const auto& context : contexts) {
|
||||
const auto placement = context.WorldCoordinateSystem();
|
||||
if (!placement) {
|
||||
@@ -202,7 +202,7 @@ std::optional<Eigen::Matrix4d> get_wcs_s(ifcopenshell::file* ifc_file) {
|
||||
}
|
||||
|
||||
template <typename Schema>
|
||||
std::optional<express::Base> get_map_unit_s(ifcopenshell::file* ifc_file) {
|
||||
std::optional<express::base> get_map_unit_s(ifcopenshell::file* ifc_file) {
|
||||
if constexpr (!is_ifc4_or_higher<Schema>::value) {
|
||||
return std::nullopt;
|
||||
} else {
|
||||
@@ -328,7 +328,7 @@ Eigen::Matrix4d helmert_meters_from_parameters(const HelmertTransformation& p,
|
||||
return M;
|
||||
}
|
||||
|
||||
std::optional<express::Base> get_map_unit(ifcopenshell::file* ifc_file) {
|
||||
std::optional<express::base> get_map_unit(ifcopenshell::file* ifc_file) {
|
||||
const auto name = ifc_file->schema()->name();
|
||||
#define IFCOPENSHELL_DISPATCH(Schema, Identifier) \
|
||||
if (name == Identifier) \
|
||||
|
||||
@@ -98,7 +98,7 @@ Eigen::Matrix4d helmert_meters_from_parameters(const HelmertTransformation& para
|
||||
// when MapUnit is absent on the IfcProjectedCRS. This is retained for UI /
|
||||
// metadata inspection; transform composition derives map unit scale from
|
||||
// IfcMapConversion.Scale instead.
|
||||
std::optional<express::Base> get_map_unit(ifcopenshell::file* ifc_file);
|
||||
std::optional<express::base> get_map_unit(ifcopenshell::file* ifc_file);
|
||||
|
||||
// "How do I rotate project east to get to grid east?" — i.e. -atan2(xao, xaa)
|
||||
// converted to degrees, anticlockwise positive. Mirrors
|
||||
|
||||
@@ -84,7 +84,7 @@ Eigen::Matrix4d axis2_placement_3d_s(const Placement& placement) {
|
||||
}
|
||||
|
||||
template <typename Schema>
|
||||
Eigen::Matrix4d get_axis2_placement_s(const express::Base& placement) {
|
||||
Eigen::Matrix4d get_axis2_placement_s(const express::base& placement) {
|
||||
if (auto axis3 = placement.template as<typename Schema::IfcAxis2Placement3D>()) {
|
||||
return axis2_placement_3d_s<Schema>(axis3);
|
||||
}
|
||||
@@ -113,7 +113,7 @@ Eigen::Matrix4d get_axis2_placement_s(const express::Base& placement) {
|
||||
}
|
||||
|
||||
template <typename Schema>
|
||||
Eigen::Matrix4d get_local_placement_s(const express::Base& placement) {
|
||||
Eigen::Matrix4d get_local_placement_s(const express::base& placement) {
|
||||
if (auto local = placement.template as<typename Schema::IfcLocalPlacement>()) {
|
||||
Eigen::Matrix4d parent = Eigen::Matrix4d::Identity();
|
||||
if (const auto relative_to = local.PlacementRelTo()) {
|
||||
@@ -131,7 +131,7 @@ Eigen::Matrix4d get_local_placement_s(const express::Base& placement) {
|
||||
// ifcopenshell.util.placement.get_storey_elevation: the Z of the storey's
|
||||
// placement in project units, falling back to the Elevation attribute.
|
||||
template <typename Schema>
|
||||
double get_storey_elevation_s(const express::Base& storey) {
|
||||
double get_storey_elevation_s(const express::base& storey) {
|
||||
const auto typed = storey.template as<typename Schema::IfcBuildingStorey>();
|
||||
if (!typed) {
|
||||
return 0.0;
|
||||
@@ -170,7 +170,7 @@ Eigen::Matrix4d axes_to_placement(const Eigen::Vector3d& origin,
|
||||
return m;
|
||||
}
|
||||
|
||||
Eigen::Matrix4d get_axis2_placement(const express::Base& placement) {
|
||||
Eigen::Matrix4d get_axis2_placement(const express::base& placement) {
|
||||
if (!placement) {
|
||||
return Eigen::Matrix4d::Identity();
|
||||
}
|
||||
@@ -183,7 +183,7 @@ Eigen::Matrix4d get_axis2_placement(const express::Base& placement) {
|
||||
unsupported_schema(name);
|
||||
}
|
||||
|
||||
Eigen::Matrix4d get_local_placement(const express::Base& placement) {
|
||||
Eigen::Matrix4d get_local_placement(const express::base& placement) {
|
||||
if (!placement) {
|
||||
return Eigen::Matrix4d::Identity();
|
||||
}
|
||||
@@ -196,7 +196,7 @@ Eigen::Matrix4d get_local_placement(const express::Base& placement) {
|
||||
unsupported_schema(name);
|
||||
}
|
||||
|
||||
double get_storey_elevation(const express::Base& storey) {
|
||||
double get_storey_elevation(const express::base& storey) {
|
||||
if (!storey) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@@ -39,17 +39,17 @@ Eigen::Matrix4d axes_to_placement(const Eigen::Vector3d& origin,
|
||||
// IfcAxis2Placement{2D,3D,Linear} / IfcAxis1Placement -> 4x4 matrix. Mirrors
|
||||
// ifcopenshell.util.placement.get_axis2placement. Returns identity for null
|
||||
// or unparseable inputs. Translation is in the IFC's project length unit.
|
||||
Eigen::Matrix4d get_axis2_placement(const express::Base& placement);
|
||||
Eigen::Matrix4d get_axis2_placement(const express::base& placement);
|
||||
|
||||
// Resolve an IfcLocalPlacement (or an IfcAxis2Placement* directly) into a
|
||||
// 4x4 matrix in the IFC project's length unit, walking the PlacementRelTo
|
||||
// chain. Mirrors ifcopenshell.util.placement.get_local_placement. Returns
|
||||
// identity for a null input.
|
||||
Eigen::Matrix4d get_local_placement(const express::Base& placement);
|
||||
Eigen::Matrix4d get_local_placement(const express::base& placement);
|
||||
|
||||
// ifcopenshell.util.placement.get_storey_elevation: the Z elevation of an
|
||||
// IfcBuildingStorey in the project's length unit — the Z of its placement, or
|
||||
// the Elevation attribute as a fallback. 0 for a non-storey or null input.
|
||||
double get_storey_elevation(const express::Base& storey);
|
||||
double get_storey_elevation(const express::base& storey);
|
||||
|
||||
#endif // PLACEMENT_H
|
||||
|
||||
+21
-21
@@ -61,7 +61,7 @@ struct has_curve_interpolation : std::false_type {};
|
||||
template <typename T>
|
||||
struct has_curve_interpolation<T, std::void_t<decltype(std::declval<T>().CurveInterpolation())>> : std::true_type {};
|
||||
|
||||
std::string schema_name(const express::Base& instance) {
|
||||
std::string schema_name(const express::base& instance) {
|
||||
return instance.declaration().schema()->name();
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ property_value from_attribute(const attribute_value& value) {
|
||||
return result;
|
||||
}
|
||||
case ifcopenshell::Argument_ENTITY_INSTANCE: {
|
||||
const express::Base instance = value;
|
||||
const express::base instance = value;
|
||||
if (instance && !instance.declaration().as_entity()) {
|
||||
return from_attribute(instance.get_attribute_value(0));
|
||||
}
|
||||
@@ -127,7 +127,7 @@ property_value from_attribute(const attribute_value& value) {
|
||||
return scalar_list(static_cast<std::vector<std::string>>(value));
|
||||
case ifcopenshell::Argument_AGGREGATE_OF_ENTITY_INSTANCE: {
|
||||
property_list result;
|
||||
for (const auto& instance : static_cast<std::vector<express::Base>>(value)) {
|
||||
for (const auto& instance : static_cast<std::vector<express::base>>(value)) {
|
||||
if (instance && !instance.declaration().as_entity()) {
|
||||
result.push_back(from_attribute(instance.get_attribute_value(0)));
|
||||
} else {
|
||||
@@ -171,7 +171,7 @@ property_value from_select_values(const Values& maybe_values) {
|
||||
}
|
||||
}
|
||||
|
||||
property_value verbose_value(const express::Base& instance,
|
||||
property_value verbose_value(const express::base& instance,
|
||||
property_value value,
|
||||
const std::optional<std::string>& value_type = std::nullopt) {
|
||||
property_map result = {
|
||||
@@ -355,7 +355,7 @@ std::optional<property_value> predefined_properties_s(
|
||||
|
||||
template <typename Schema>
|
||||
std::optional<property_value> get_property_definition_s(
|
||||
const express::Base& definition,
|
||||
const express::base& definition,
|
||||
const std::optional<std::string>& property_name,
|
||||
bool verbose) {
|
||||
if (!definition) {
|
||||
@@ -405,8 +405,8 @@ std::optional<property_value> get_property_definition_s(
|
||||
}
|
||||
|
||||
template <typename Definition>
|
||||
express::Base concrete_definition(const Definition& definition) {
|
||||
if constexpr (std::is_base_of_v<express::Select, Definition>) {
|
||||
express::base concrete_definition(const Definition& definition) {
|
||||
if constexpr (std::is_base_of_v<express::select, Definition>) {
|
||||
return definition.concrete();
|
||||
} else {
|
||||
return definition;
|
||||
@@ -414,7 +414,7 @@ express::Base concrete_definition(const Definition& definition) {
|
||||
}
|
||||
|
||||
template <typename Schema>
|
||||
bool definition_is_pset_s(const express::Base& definition) {
|
||||
bool definition_is_pset_s(const express::base& definition) {
|
||||
if (definition.template as<typename Schema::IfcPropertySet>()) {
|
||||
return true;
|
||||
}
|
||||
@@ -432,7 +432,7 @@ bool definition_is_pset_s(const express::Base& definition) {
|
||||
}
|
||||
|
||||
template <typename Schema>
|
||||
std::optional<std::string> definition_name_s(const express::Base& definition) {
|
||||
std::optional<std::string> definition_name_s(const express::base& definition) {
|
||||
if (auto pset = definition.template as<typename Schema::IfcPropertySet>()) {
|
||||
return pset.Name();
|
||||
}
|
||||
@@ -458,7 +458,7 @@ std::optional<std::string> definition_name_s(const express::Base& definition) {
|
||||
|
||||
template <typename Schema>
|
||||
void merge_definition_s(element_properties& result,
|
||||
const express::Base& definition,
|
||||
const express::base& definition,
|
||||
bool psets_only,
|
||||
bool qtos_only,
|
||||
bool verbose) {
|
||||
@@ -505,7 +505,7 @@ typename Schema::IfcTypeObject get_type_s(const typename Schema::IfcObject& obje
|
||||
}
|
||||
|
||||
template <typename Schema>
|
||||
element_properties get_psets_s(const express::Base& element,
|
||||
element_properties get_psets_s(const express::base& element,
|
||||
bool psets_only,
|
||||
bool qtos_only,
|
||||
bool should_inherit,
|
||||
@@ -578,7 +578,7 @@ element_properties get_psets_s(const express::Base& element,
|
||||
}
|
||||
|
||||
template <typename Schema>
|
||||
std::optional<property_value> get_inherited_property_s(const express::Base& element,
|
||||
std::optional<property_value> get_inherited_property_s(const express::base& element,
|
||||
const std::string& pset_name,
|
||||
const std::string& property_name,
|
||||
bool psets_only,
|
||||
@@ -605,7 +605,7 @@ std::optional<property_value> get_inherited_property_s(const express::Base& elem
|
||||
}
|
||||
|
||||
template <typename Schema, typename Entity>
|
||||
std::vector<Entity> cast_entities(const std::vector<express::Base>& values) {
|
||||
std::vector<Entity> cast_entities(const std::vector<express::base>& values) {
|
||||
std::vector<Entity> result;
|
||||
result.reserve(values.size());
|
||||
for (const auto& value : values) {
|
||||
@@ -624,7 +624,7 @@ void print_value(std::ostream& stream, const property_value& value) {
|
||||
stream << "null";
|
||||
} else if constexpr (std::is_same_v<T, bool>) {
|
||||
stream << (item ? "true" : "false");
|
||||
} else if constexpr (std::is_same_v<T, express::Base>) {
|
||||
} else if constexpr (std::is_same_v<T, express::base>) {
|
||||
if (item) {
|
||||
item.to_string(stream);
|
||||
} else {
|
||||
@@ -667,7 +667,7 @@ std::ostream& operator<<(std::ostream& stream, const property_value& value) {
|
||||
return stream;
|
||||
}
|
||||
|
||||
element_properties get_psets(const express::Base& element,
|
||||
element_properties get_psets(const express::base& element,
|
||||
bool psets_only,
|
||||
bool qtos_only,
|
||||
bool should_inherit,
|
||||
@@ -685,7 +685,7 @@ element_properties get_psets(const express::Base& element,
|
||||
unsupported_schema(name);
|
||||
}
|
||||
|
||||
std::optional<property_value> get_pset(const express::Base& element,
|
||||
std::optional<property_value> get_pset(const express::base& element,
|
||||
const std::string& name,
|
||||
const std::optional<std::string>& property_name,
|
||||
bool psets_only,
|
||||
@@ -719,7 +719,7 @@ std::optional<property_value> get_pset(const express::Base& element,
|
||||
}
|
||||
|
||||
std::optional<property_value> get_property_definition(
|
||||
const express::Base& definition,
|
||||
const express::base& definition,
|
||||
const std::optional<std::string>& property_name,
|
||||
bool verbose) {
|
||||
if (!definition) {
|
||||
@@ -734,7 +734,7 @@ std::optional<property_value> get_property_definition(
|
||||
unsupported_schema(name);
|
||||
}
|
||||
|
||||
std::optional<property_value> get_quantity(const std::vector<express::Base>& quantities,
|
||||
std::optional<property_value> get_quantity(const std::vector<express::base>& quantities,
|
||||
const std::string& name,
|
||||
bool verbose) {
|
||||
if (quantities.empty()) {
|
||||
@@ -752,7 +752,7 @@ std::optional<property_value> get_quantity(const std::vector<express::Base>& qua
|
||||
unsupported_schema(schema);
|
||||
}
|
||||
|
||||
property_map get_quantities(const std::vector<express::Base>& quantities, bool verbose) {
|
||||
property_map get_quantities(const std::vector<express::base>& quantities, bool verbose) {
|
||||
if (quantities.empty()) {
|
||||
return {};
|
||||
}
|
||||
@@ -767,7 +767,7 @@ property_map get_quantities(const std::vector<express::Base>& quantities, bool v
|
||||
unsupported_schema(schema);
|
||||
}
|
||||
|
||||
std::optional<property_value> get_property(const std::vector<express::Base>& properties,
|
||||
std::optional<property_value> get_property(const std::vector<express::base>& properties,
|
||||
const std::string& name,
|
||||
bool verbose) {
|
||||
if (properties.empty()) {
|
||||
@@ -785,7 +785,7 @@ std::optional<property_value> get_property(const std::vector<express::Base>& pro
|
||||
unsupported_schema(schema);
|
||||
}
|
||||
|
||||
property_map get_properties(const std::vector<express::Base>& properties, bool verbose) {
|
||||
property_map get_properties(const std::vector<express::base>& properties, bool verbose) {
|
||||
if (properties.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
+9
-9
@@ -43,7 +43,7 @@ using element_properties = std::map<std::string, property_map>;
|
||||
// IFC null. Entity values are retained for compound property metadata that
|
||||
// cannot be flattened to a scalar.
|
||||
struct property_value {
|
||||
using storage_type = std::variant<std::monostate, bool, std::int64_t, double, std::string, express::Base, property_list, property_map>;
|
||||
using storage_type = std::variant<std::monostate, bool, std::int64_t, double, std::string, express::base, property_list, property_map>;
|
||||
|
||||
storage_type value;
|
||||
|
||||
@@ -55,7 +55,7 @@ struct property_value {
|
||||
property_value(double value) : value(value) {}
|
||||
property_value(const char* value) : value(std::string(value)) {}
|
||||
property_value(std::string value) : value(std::move(value)) {}
|
||||
property_value(express::Base value) : value(std::move(value)) {}
|
||||
property_value(express::base value) : value(std::move(value)) {}
|
||||
property_value(property_list value) : value(std::move(value)) {}
|
||||
property_value(property_map value) : value(std::move(value)) {}
|
||||
|
||||
@@ -73,7 +73,7 @@ std::ostream& operator<<(std::ostream& stream, const property_value& value);
|
||||
// the returned value contains a property_map. A selected IFC null property is
|
||||
// represented by an engaged optional containing a null property_value.
|
||||
std::optional<property_value> get_pset(
|
||||
const express::Base& element,
|
||||
const express::base& element,
|
||||
const std::string& name,
|
||||
const std::optional<std::string>& property_name = std::nullopt,
|
||||
bool psets_only = false,
|
||||
@@ -83,27 +83,27 @@ std::optional<property_value> get_pset(
|
||||
|
||||
// Mirrors ifcopenshell.util.element.get_psets, including occurrence-over-type
|
||||
// precedence and the definition instance id in each returned property map.
|
||||
element_properties get_psets(const express::Base& element,
|
||||
element_properties get_psets(const express::base& element,
|
||||
bool psets_only = false,
|
||||
bool qtos_only = false,
|
||||
bool should_inherit = true,
|
||||
bool verbose = false);
|
||||
|
||||
std::optional<property_value> get_property_definition(
|
||||
const express::Base& definition,
|
||||
const express::base& definition,
|
||||
const std::optional<std::string>& property_name = std::nullopt,
|
||||
bool verbose = false);
|
||||
|
||||
std::optional<property_value> get_quantity(const std::vector<express::Base>& quantities,
|
||||
std::optional<property_value> get_quantity(const std::vector<express::base>& quantities,
|
||||
const std::string& name,
|
||||
bool verbose = false);
|
||||
property_map get_quantities(const std::vector<express::Base>& quantities,
|
||||
property_map get_quantities(const std::vector<express::base>& quantities,
|
||||
bool verbose = false);
|
||||
|
||||
std::optional<property_value> get_property(const std::vector<express::Base>& properties,
|
||||
std::optional<property_value> get_property(const std::vector<express::base>& properties,
|
||||
const std::string& name,
|
||||
bool verbose = false);
|
||||
property_map get_properties(const std::vector<express::Base>& properties,
|
||||
property_map get_properties(const std::vector<express::base>& properties,
|
||||
bool verbose = false);
|
||||
|
||||
#endif // PSET_H
|
||||
|
||||
+10
-10
@@ -212,7 +212,7 @@ std::string to_lower(const std::string& s) {
|
||||
throw ifcopenshell::exception("No helper implementation was built for schema " + name);
|
||||
}
|
||||
|
||||
std::optional<double> numeric_value(const express::Base& value) {
|
||||
std::optional<double> numeric_value(const express::base& value) {
|
||||
if (!value) {
|
||||
return std::nullopt;
|
||||
}
|
||||
@@ -230,7 +230,7 @@ std::optional<double> numeric_value(const express::Base& value) {
|
||||
}
|
||||
|
||||
template <typename Schema>
|
||||
std::optional<double> si_scale_from_named_unit_s(express::Base unit) {
|
||||
std::optional<double> si_scale_from_named_unit_s(express::base unit) {
|
||||
double scale = 1.0;
|
||||
while (auto conversion = unit.template as<typename Schema::IfcConversionBasedUnit>()) {
|
||||
if (const auto it = SI_CONVERSIONS.find(to_lower(conversion.Name()));
|
||||
@@ -271,7 +271,7 @@ std::optional<double> si_scale_from_named_unit_s(express::Base unit) {
|
||||
}
|
||||
|
||||
template <typename Schema>
|
||||
std::optional<express::Base> get_unit_assignment_s(ifcopenshell::file* ifc_file) {
|
||||
std::optional<express::base> get_unit_assignment_s(ifcopenshell::file* ifc_file) {
|
||||
const auto projects = ifc_file->template instances_by_type<typename Schema::IfcProject>();
|
||||
if (projects.empty()) {
|
||||
return std::nullopt;
|
||||
@@ -284,7 +284,7 @@ std::optional<express::Base> get_unit_assignment_s(ifcopenshell::file* ifc_file)
|
||||
}
|
||||
|
||||
template <typename Schema>
|
||||
std::optional<express::Base> get_project_unit_s(ifcopenshell::file* ifc_file,
|
||||
std::optional<express::base> get_project_unit_s(ifcopenshell::file* ifc_file,
|
||||
const std::string& unit_type) {
|
||||
const auto assignment = get_unit_assignment_s<Schema>(ifc_file);
|
||||
if (!assignment) {
|
||||
@@ -316,7 +316,7 @@ double calculate_unit_scale_s(ifcopenshell::file* ifc_file, const std::string& u
|
||||
}
|
||||
|
||||
template <typename Schema>
|
||||
void unit_name_s(const express::Base& unit, std::string& prefix, std::string& name) {
|
||||
void unit_name_s(const express::base& unit, std::string& prefix, std::string& name) {
|
||||
prefix.clear();
|
||||
name.clear();
|
||||
if (auto si = unit.template as<typename Schema::IfcSIUnit>()) {
|
||||
@@ -332,7 +332,7 @@ void unit_name_s(const express::Base& unit, std::string& prefix, std::string& na
|
||||
}
|
||||
|
||||
template <typename Schema>
|
||||
double convert_unit_s(double value, const express::Base& from_unit, const express::Base& to_unit) {
|
||||
double convert_unit_s(double value, const express::base& from_unit, const express::base& to_unit) {
|
||||
std::string from_prefix;
|
||||
std::string from_name;
|
||||
std::string to_prefix;
|
||||
@@ -352,7 +352,7 @@ double get_prefix_multiplier(const std::string& prefix) {
|
||||
return (it == SI_PREFIXES.end()) ? 1.0 : it->second;
|
||||
}
|
||||
|
||||
std::optional<double> si_scale_from_named_unit(express::Base unit) {
|
||||
std::optional<double> si_scale_from_named_unit(express::base unit) {
|
||||
if (!unit) {
|
||||
return std::nullopt;
|
||||
}
|
||||
@@ -365,7 +365,7 @@ std::optional<double> si_scale_from_named_unit(express::Base unit) {
|
||||
unsupported_schema(name);
|
||||
}
|
||||
|
||||
std::optional<express::Base> get_unit_assignment(ifcopenshell::file* ifc_file) {
|
||||
std::optional<express::base> get_unit_assignment(ifcopenshell::file* ifc_file) {
|
||||
const auto name = ifc_file->schema()->name();
|
||||
#define IFCOPENSHELL_DISPATCH(Schema, Identifier) \
|
||||
if (name == Identifier) \
|
||||
@@ -375,7 +375,7 @@ std::optional<express::Base> get_unit_assignment(ifcopenshell::file* ifc_file) {
|
||||
unsupported_schema(name);
|
||||
}
|
||||
|
||||
std::optional<express::Base> get_project_unit(ifcopenshell::file* ifc_file,
|
||||
std::optional<express::base> get_project_unit(ifcopenshell::file* ifc_file,
|
||||
const std::string& unit_type) {
|
||||
const auto name = ifc_file->schema()->name();
|
||||
#define IFCOPENSHELL_DISPATCH(Schema, Identifier) \
|
||||
@@ -434,7 +434,7 @@ double convert(double value,
|
||||
return value;
|
||||
}
|
||||
|
||||
double convert_unit(double value, express::Base from_unit, express::Base to_unit) {
|
||||
double convert_unit(double value, express::base from_unit, express::base to_unit) {
|
||||
if (!from_unit || !to_unit) {
|
||||
return value;
|
||||
}
|
||||
|
||||
+4
-4
@@ -58,15 +58,15 @@ double get_prefix_multiplier(const std::string& prefix);
|
||||
// value_in_unit * scale == value_in_si_base
|
||||
// Walks IfcConversionBasedUnit chains down to IfcSIUnit. Returns nullopt
|
||||
// when the chain bottoms out in IfcContextDependentUnit (cannot convert).
|
||||
std::optional<double> si_scale_from_named_unit(express::Base named_unit);
|
||||
std::optional<double> si_scale_from_named_unit(express::base named_unit);
|
||||
|
||||
// IfcProject.UnitsInContext (the IfcUnitAssignment). Returns nullopt if
|
||||
// the file has no project or no assignment.
|
||||
std::optional<express::Base> get_unit_assignment(ifcopenshell::file* ifc_file);
|
||||
std::optional<express::base> get_unit_assignment(ifcopenshell::file* ifc_file);
|
||||
|
||||
// First unit in the project's IfcUnitAssignment matching `unit_type`
|
||||
// (e.g. "LENGTHUNIT"). Returns nullopt if not found.
|
||||
std::optional<express::Base> get_project_unit(ifcopenshell::file* ifc_file,
|
||||
std::optional<express::base> get_project_unit(ifcopenshell::file* ifc_file,
|
||||
const std::string& unit_type);
|
||||
|
||||
// Project unit -> SI base scale (e.g. project in mm => 0.001). Defaults
|
||||
@@ -86,6 +86,6 @@ double convert(double value,
|
||||
// Convert between two IfcNamedUnit entities. Pulls Name and Prefix off each
|
||||
// and delegates to convert(). IfcConversionBasedUnit names that don't appear
|
||||
// in SI_CONVERSIONS return the value unchanged.
|
||||
double convert_unit(double value, express::Base from_unit, express::Base to_unit);
|
||||
double convert_unit(double value, express::base from_unit, express::base to_unit);
|
||||
|
||||
#endif // UNIT_H
|
||||
|
||||
@@ -223,9 +223,9 @@ void fix_quantities(ifcopenshell::file&, bool, bool, bool, logger& logger = ::lo
|
||||
std::string format_duration(time_t start, time_t end);
|
||||
|
||||
/// @todo make the filters non-global
|
||||
IfcGeom::entity_filter entity_filter; // Entity filter is used always by default.
|
||||
IfcGeom::layer_filter layer_filter;
|
||||
IfcGeom::attribute_filter attribute_filter;
|
||||
ifcopenshell::geom::entity_filter entity_filter; // Entity filter is used always by default.
|
||||
ifcopenshell::geom::layer_filter layer_filter;
|
||||
ifcopenshell::geom::attribute_filter attribute_filter;
|
||||
|
||||
struct geom_filter
|
||||
{
|
||||
@@ -247,7 +247,7 @@ struct exclusion_traverse_filter : public geom_filter { exclusion_traverse_filte
|
||||
|
||||
size_t read_filters_from_file(const std::string&, inclusion_filter&, inclusion_traverse_filter&, exclusion_filter&, exclusion_traverse_filter&);
|
||||
void parse_filter(geom_filter &, const std::vector<std::string>&);
|
||||
std::vector<ifcopenshell::geometry::filter_t> setup_filters(const std::vector<geom_filter>&, const std::string&);
|
||||
std::vector<ifcopenshell::geom::filter_t> setup_filters(const std::vector<geom_filter>&, const std::string&);
|
||||
|
||||
bool init_input_file(const std::string& filename, ifcopenshell::file*& ifc_file, bool no_progress, bool mmap, bool bypass_properties=false, logger& logger = ::logger::root());
|
||||
|
||||
@@ -334,7 +334,7 @@ int main(int argc, char** argv) {
|
||||
// none, convex-decomposition, minkowski-triangles or halfspace-snapping
|
||||
std::string exterior_only_algo;
|
||||
|
||||
ifcopenshell::geometry::Settings geometry_settings;
|
||||
ifcopenshell::geom::settings settings;
|
||||
|
||||
po::options_description geom_options("Geometry options");
|
||||
geom_options.add_options()
|
||||
@@ -389,7 +389,7 @@ int main(int argc, char** argv) {
|
||||
"Typically these are representations of type Body or Facetation. ")
|
||||
;
|
||||
|
||||
geometry_settings.define_options(geom_options);
|
||||
settings.define_options(geom_options);
|
||||
|
||||
std::string bounds;
|
||||
#ifdef HAVE_ICU
|
||||
@@ -397,8 +397,6 @@ int main(int argc, char** argv) {
|
||||
#endif
|
||||
short precision;
|
||||
|
||||
ifcopenshell::geometry::SerializerSettings serializer_settings;
|
||||
|
||||
po::options_description serializer_options("Serialization options");
|
||||
serializer_options.add_options()
|
||||
#ifdef HAVE_ICU
|
||||
@@ -408,8 +406,6 @@ int main(int argc, char** argv) {
|
||||
#endif
|
||||
;
|
||||
|
||||
serializer_settings.define_options(serializer_options);
|
||||
|
||||
po::options_description cmdline_options;
|
||||
cmdline_options.add(generic_options).add(fileio_options).add(geom_options).add(ifc_options).add(serializer_options);
|
||||
|
||||
@@ -511,7 +507,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
if (!default_material_filename.empty()) {
|
||||
try {
|
||||
IfcGeom::set_default_style_file(ifcopenshell::path::to_utf8(default_material_filename));
|
||||
ifcopenshell::geom::set_default_style_file(ifcopenshell::path::to_utf8(default_material_filename));
|
||||
} catch (const std::exception& e) {
|
||||
cerr_ << "[error] Could not read default material file:" << std::endl;
|
||||
cerr_ << e.what() << std::endl;
|
||||
@@ -591,7 +587,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
ifcopenshell::file* ifc_file = 0;
|
||||
|
||||
boost::optional<std::list<IfcGeom::Element*>> elems_from_adaptor;
|
||||
boost::optional<std::list<ifcopenshell::geom::element*>> elems_from_adaptor;
|
||||
|
||||
const path_t IFC = ifcopenshell::path::from_utf8(".ifc");
|
||||
|
||||
@@ -622,7 +618,7 @@ int main(int argc, char** argv) {
|
||||
context.schema_name = ifc_file ? ifc_file->schema()->name() : document_serializer_info->schema_name;
|
||||
context.stream = use_input_filename;
|
||||
|
||||
boost::shared_ptr<Serializer> serializer = document_serializer_registry.create(output_extension_utf8, context);
|
||||
boost::shared_ptr<serializer> serializer = document_serializer_registry.create(output_extension_utf8, context);
|
||||
if (serializer->is_streaming() != use_input_filename) {
|
||||
throw ifcopenshell::exception("Selected document serializer streaming mode does not match its registry metadata");
|
||||
}
|
||||
@@ -698,7 +694,7 @@ int main(int argc, char** argv) {
|
||||
if (exclude_filter.type != geom_filter::UNUSED) { used_filters.push_back(exclude_filter); }
|
||||
if (exclude_traverse_filter.type != geom_filter::UNUSED) { used_filters.push_back(exclude_traverse_filter); }
|
||||
|
||||
std::vector<ifcopenshell::geometry::filter_t> filter_funcs = setup_filters(used_filters, ifcopenshell::path::to_utf8(output_extension));
|
||||
std::vector<ifcopenshell::geom::filter_t> filter_funcs = setup_filters(used_filters, ifcopenshell::path::to_utf8(output_extension));
|
||||
if (filter_funcs.empty()) {
|
||||
cerr_ << "[error] Failed to set up geometry filters\n";
|
||||
return EXIT_FAILURE;
|
||||
@@ -727,21 +723,21 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
|
||||
// The OS will clean up for us if there is a leak
|
||||
geometry_settings.get<ifcopenshell::geometry::settings::OcctNoCleanTriangulation>().value = true;
|
||||
settings.get<ifcopenshell::geom::settings::OcctNoCleanTriangulation>().value = true;
|
||||
|
||||
if (geometry_settings.get<ifcopenshell::geometry::settings::PermissiveShapeReuse>().get()) {
|
||||
geometry_settings.get<ifcopenshell::geometry::settings::NoParallelMapping>().value = true;
|
||||
if (settings.get<ifcopenshell::geom::settings::PermissiveShapeReuse>().get()) {
|
||||
settings.get<ifcopenshell::geom::settings::NoParallelMapping>().value = true;
|
||||
}
|
||||
|
||||
if (vmap[ifcopenshell::geometry::settings::WeldVertices::name].defaulted()) {
|
||||
geometry_settings.get<ifcopenshell::geometry::settings::WeldVertices>().value = false;
|
||||
if (vmap[ifcopenshell::geom::settings::WeldVertices::name].defaulted()) {
|
||||
settings.get<ifcopenshell::geom::settings::WeldVertices>().value = false;
|
||||
}
|
||||
|
||||
if (geometry_settings.get<ifcopenshell::geometry::settings::ForceSpaceTransparency>().has()) {
|
||||
IfcGeom::update_default_style("IfcSpace")->transparency = geometry_settings.get<ifcopenshell::geometry::settings::ForceSpaceTransparency>().get();
|
||||
if (settings.get<ifcopenshell::geom::settings::ForceSpaceTransparency>().has()) {
|
||||
ifcopenshell::geom::update_default_style("IfcSpace")->transparency = settings.get<ifcopenshell::geom::settings::ForceSpaceTransparency>().get();
|
||||
}
|
||||
|
||||
if (geometry_settings.get<ifcopenshell::geometry::settings::UseElementHierarchy>().get() &&
|
||||
if (settings.get<ifcopenshell::geom::settings::UseElementHierarchy>().get() &&
|
||||
!geometry_serializer_info->supports_user_element_hierarchy) {
|
||||
cerr_ << "[error] --use-element-hierarchy is not supported by the selected geometry serializer.\n";
|
||||
write_log(!quiet);
|
||||
@@ -753,11 +749,10 @@ int main(int argc, char** argv) {
|
||||
ifcopenshell::serializers::geometry_serializer_context serializer_context{
|
||||
ifcopenshell::path::to_utf8(output_filename),
|
||||
ifcopenshell::path::to_utf8(output_temp_filename),
|
||||
geometry_settings,
|
||||
serializer_settings
|
||||
settings
|
||||
};
|
||||
|
||||
boost::shared_ptr<GeometrySerializer> serializer; /**< @todo use std::unique_ptr when possible */
|
||||
boost::shared_ptr<geometry_serializer> serializer; /**< @todo use std::unique_ptr when possible */
|
||||
try {
|
||||
geometry_serializer_registry.configure(output_extension_utf8, serializer_context);
|
||||
serializer = geometry_serializer_registry.create(output_extension_utf8, serializer_context);
|
||||
@@ -771,17 +766,17 @@ int main(int argc, char** argv) {
|
||||
|
||||
const bool is_tesselated = serializer->isTesselated(); // isTesselated() doesn't change at run-time
|
||||
if (!is_tesselated) {
|
||||
if (geometry_settings.get<ifcopenshell::geometry::settings::WeldVertices>().get()) {
|
||||
if (settings.get<ifcopenshell::geom::settings::WeldVertices>().get()) {
|
||||
logger.notice("SYS", 16, "Weld vertices setting ignored when writing non-tesselated output");
|
||||
}
|
||||
if (geometry_settings.get<ifcopenshell::geometry::settings::GenerateUvs>().get()) {
|
||||
if (settings.get<ifcopenshell::geom::settings::GenerateUvs>().get()) {
|
||||
logger.notice("SYS", 17, "Generate UVs setting ignored when writing non-tesselated output");
|
||||
}
|
||||
if (center_model || center_model_geometry) {
|
||||
logger.notice("SYS", 18, "Centering/offsetting model setting ignored when writing non-tesselated output");
|
||||
}
|
||||
|
||||
geometry_settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
|
||||
settings.get<ifcopenshell::geom::settings::IteratorOutput>().value = ifcopenshell::geom::settings::NATIVE;
|
||||
}
|
||||
|
||||
if (!serializer->ready()) {
|
||||
@@ -824,7 +819,7 @@ int main(int argc, char** argv) {
|
||||
msg << "Using model rotation (" << rotation[0] << "," << rotation[1] << "," << rotation[2] << "," << rotation[3] << ")";
|
||||
logger.notice("SYS", 19, msg.str());
|
||||
|
||||
geometry_settings.get<ifcopenshell::geometry::settings::ModelRotation>().value = rotation;
|
||||
settings.get<ifcopenshell::geom::settings::ModelRotation>().value = rotation;
|
||||
}
|
||||
|
||||
if (model_offset && (center_model || center_model_geometry)) {
|
||||
@@ -845,13 +840,13 @@ int main(int argc, char** argv) {
|
||||
msg << std::setprecision(std::numeric_limits<double>::max_digits10) << "Using model offset (" << offset[0] << "," << offset[1] << "," << offset[2] << ")";
|
||||
logger.notice("SYS", 20, msg.str());
|
||||
|
||||
geometry_settings.get<ifcopenshell::geometry::settings::ModelOffset>().value = offset;
|
||||
settings.get<ifcopenshell::geom::settings::ModelOffset>().value = offset;
|
||||
}
|
||||
|
||||
if (is_tesselated && (center_model || center_model_geometry)) {
|
||||
std::vector<double> offset(3);
|
||||
|
||||
IfcGeom::Iterator tmp_context_iterator(ifcopenshell::geometry::kernels::construct(ifc_file, geometry_kernel, geometry_settings), geometry_settings, ifc_file, filter_funcs, num_threads, logger);
|
||||
ifcopenshell::geom::iterator tmp_context_iterator(ifcopenshell::geom::kernels::construct(ifc_file, geometry_kernel, settings), settings, ifc_file, filter_funcs, num_threads, logger);
|
||||
|
||||
time_t start, end;
|
||||
time(&start);
|
||||
@@ -883,21 +878,21 @@ int main(int argc, char** argv) {
|
||||
msg << std::setprecision (std::numeric_limits<double>::max_digits10) << "Using model offset (" << offset[0] << "," << offset[1] << "," << offset[2] << ")";
|
||||
logger.notice("SYS", 21, msg.str());
|
||||
|
||||
geometry_settings.get<ifcopenshell::geometry::settings::ModelOffset>().value = offset;
|
||||
settings.get<ifcopenshell::geom::settings::ModelOffset>().value = offset;
|
||||
}
|
||||
|
||||
// backwards compatibility
|
||||
if (vmap.count("plan") && vmap.count("model")) {
|
||||
geometry_settings.get<ifcopenshell::geometry::settings::OutputDimensionality>().value = ifcopenshell::geometry::settings::CURVES_SURFACES_AND_SOLIDS;
|
||||
settings.get<ifcopenshell::geom::settings::OutputDimensionality>().value = ifcopenshell::geom::settings::CURVES_SURFACES_AND_SOLIDS;
|
||||
} else if (vmap.count("model")) {
|
||||
geometry_settings.get<ifcopenshell::geometry::settings::OutputDimensionality>().value = ifcopenshell::geometry::settings::SURFACES_AND_SOLIDS;
|
||||
settings.get<ifcopenshell::geom::settings::OutputDimensionality>().value = ifcopenshell::geom::settings::SURFACES_AND_SOLIDS;
|
||||
} else if (vmap.count("plan")) {
|
||||
geometry_settings.get<ifcopenshell::geometry::settings::OutputDimensionality>().value = ifcopenshell::geometry::settings::CURVES;
|
||||
settings.get<ifcopenshell::geom::settings::OutputDimensionality>().value = ifcopenshell::geom::settings::CURVES;
|
||||
}
|
||||
|
||||
std::unique_ptr<IfcGeom::Iterator> context_iterator;
|
||||
std::unique_ptr<ifcopenshell::geom::iterator> context_iterator;
|
||||
if (!elems_from_adaptor) {
|
||||
context_iterator.reset(new IfcGeom::Iterator(ifcopenshell::geometry::kernels::construct(ifc_file, geometry_kernel, geometry_settings), geometry_settings, ifc_file, filter_funcs, num_threads, logger));
|
||||
context_iterator.reset(new ifcopenshell::geom::iterator(ifcopenshell::geom::kernels::construct(ifc_file, geometry_kernel, settings), settings, ifc_file, filter_funcs, num_threads, logger));
|
||||
}
|
||||
|
||||
logger.message(::logger::LOG_PERF, "file geometry conversion");
|
||||
@@ -914,7 +909,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
serializer->setFile(*ifc_file);
|
||||
|
||||
if (context_iterator && geometry_settings.get<ifcopenshell::geometry::settings::ConvertBackUnits>().get()) {
|
||||
if (context_iterator && settings.get<ifcopenshell::geom::settings::ConvertBackUnits>().get()) {
|
||||
serializer->setUnitNameAndMagnitude(context_iterator->unit_name(), static_cast<float>(context_iterator->unit_magnitude()));
|
||||
} else {
|
||||
serializer->setUnitNameAndMagnitude("METER", 1.0f);
|
||||
@@ -928,11 +923,11 @@ int main(int argc, char** argv) {
|
||||
logger.status("Creating geometry...");
|
||||
}
|
||||
|
||||
// The functions IfcGeom::Iterator::get() and IfcGeom::Iterator::next()
|
||||
// The functions ifcopenshell::geom::iterator::get() and ifcopenshell::geom::iterator::next()
|
||||
// wrap an iterator of all geometrical products in the Ifc file.
|
||||
// IfcGeom::Iterator::get() returns an IfcGeom::TriangulationElement or
|
||||
// -BRepElement pointer, based on current settings. (see Iterator.h
|
||||
// for definition) IfcGeom::Iterator::next() is used to poll whether more
|
||||
// ifcopenshell::geom::iterator::get() returns an ifcopenshell::geom::triangulation_element or
|
||||
// -brep_element pointer, based on current settings. (see Iterator.h
|
||||
// for definition) ifcopenshell::geom::iterator::next() is used to poll whether more
|
||||
// geometrical entities are available. None of these functions throw
|
||||
// exceptions, neither for parsing errors or geometrical errors. Upon
|
||||
// calling next() the entity to be returned has already been processed, a
|
||||
@@ -940,22 +935,22 @@ int main(int argc, char** argv) {
|
||||
// available.
|
||||
size_t num_created = 0;
|
||||
|
||||
std::list<IfcGeom::Element*>::const_iterator elems_from_adaptor_it;
|
||||
std::list<ifcopenshell::geom::element*>::const_iterator elems_from_adaptor_it;
|
||||
if (elems_from_adaptor) {
|
||||
elems_from_adaptor_it = elems_from_adaptor->begin();
|
||||
}
|
||||
|
||||
while (true) {
|
||||
|
||||
IfcGeom::Element* geom_object = elems_from_adaptor ? *elems_from_adaptor_it : context_iterator->get();
|
||||
ifcopenshell::geom::element* geom_object = elems_from_adaptor ? *elems_from_adaptor_it : context_iterator->get();
|
||||
|
||||
if (is_tesselated)
|
||||
{
|
||||
serializer->write(static_cast<const IfcGeom::TriangulationElement*>(geom_object));
|
||||
serializer->write(static_cast<const ifcopenshell::geom::triangulation_element*>(geom_object));
|
||||
}
|
||||
else
|
||||
{
|
||||
serializer->write(static_cast<const IfcGeom::BRepElement*>(geom_object));
|
||||
serializer->write(static_cast<const ifcopenshell::geom::brep_element*>(geom_object));
|
||||
}
|
||||
|
||||
if (!no_progress) {
|
||||
@@ -1028,7 +1023,7 @@ int main(int argc, char** argv) {
|
||||
output_temp_filename << "' for the conversion result.";
|
||||
}
|
||||
|
||||
if (geometry_settings.get<ifcopenshell::geometry::settings::ValidateQuantities>().get() && logger.max_severity() >= ::logger::LOG_ERROR) {
|
||||
if (settings.get<ifcopenshell::geom::settings::ValidateQuantities>().get() && logger.max_severity() >= ::logger::LOG_ERROR) {
|
||||
logger.error("SYS", 24, "Errors encountered during processing.");
|
||||
successful = false;
|
||||
}
|
||||
@@ -1265,9 +1260,9 @@ void validate(boost::any& v, const std::vector<std::string>& values, exclusion_t
|
||||
|
||||
/// @todo Clean up this filter initialization code further.
|
||||
/// @return References to the used filter functors, if none an error occurred.
|
||||
std::vector<ifcopenshell::geometry::filter_t> setup_filters(const std::vector<geom_filter>& filters, const std::string& output_extension)
|
||||
std::vector<ifcopenshell::geom::filter_t> setup_filters(const std::vector<geom_filter>& filters, const std::string& output_extension)
|
||||
{
|
||||
std::vector<ifcopenshell::geometry::filter_t> filter_funcs;
|
||||
std::vector<ifcopenshell::geom::filter_t> filter_funcs;
|
||||
for(auto& f: filters) {
|
||||
if (f.type == geom_filter::ENTITY_TYPE) {
|
||||
entity_filter.include = f.include;
|
||||
@@ -1307,13 +1302,13 @@ std::vector<ifcopenshell::geometry::filter_t> setup_filters(const std::vector<ge
|
||||
namespace latebound_access {
|
||||
|
||||
template <typename T>
|
||||
void set(express::Base inst, const std::string& attr, T t);
|
||||
void set(express::base inst, const std::string& attr, T t);
|
||||
|
||||
template <typename T>
|
||||
void set_enumeration(express::Base, const std::string&, const ifcopenshell::enumeration_type*, T) {}
|
||||
void set_enumeration(express::base, const std::string&, const ifcopenshell::enumeration_type*, T) {}
|
||||
|
||||
template <>
|
||||
void set_enumeration(express::Base inst, const std::string& attr, const ifcopenshell::enumeration_type* enum_type, std::string t) {
|
||||
void set_enumeration(express::base inst, const std::string& attr, const ifcopenshell::enumeration_type* enum_type, std::string t) {
|
||||
std::vector<std::string>::const_iterator it = std::find(
|
||||
enum_type->enumeration_items().begin(),
|
||||
enum_type->enumeration_items().end(),
|
||||
@@ -1323,7 +1318,7 @@ namespace latebound_access {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void set(express::Base inst, const std::string& attr, T t) {
|
||||
void set(express::base inst, const std::string& attr, T t) {
|
||||
auto decl = inst.declaration().as_entity();
|
||||
auto i = decl->attribute_index(attr);
|
||||
|
||||
@@ -1335,7 +1330,7 @@ namespace latebound_access {
|
||||
}
|
||||
}
|
||||
|
||||
express::Base create(ifcopenshell::file& f, const std::string& entity) {
|
||||
express::base create(ifcopenshell::file& f, const std::string& entity) {
|
||||
auto decl = f.schema()->declaration_by_name(entity);
|
||||
return f.create(decl);
|
||||
}
|
||||
@@ -1343,7 +1338,7 @@ namespace latebound_access {
|
||||
|
||||
void fix_quantities(ifcopenshell::file& f, bool no_progress, bool quiet, bool stderr_progress, logger& logger) {
|
||||
{
|
||||
auto delete_reversed = [&f](const std::vector<express::Base>& insts) {
|
||||
auto delete_reversed = [&f](const std::vector<express::base>& insts) {
|
||||
// Lists are traversed back to front as the list may be mutated when
|
||||
// instances are removed from the grouping by type.
|
||||
for (auto it = insts.end() - 1; it >= insts.begin(); --it) {
|
||||
@@ -1365,7 +1360,7 @@ void fix_quantities(ifcopenshell::file& f, bool no_progress, bool quiet, bool st
|
||||
auto element_quantities = f.instances_by_type("IfcElementQuantity");
|
||||
|
||||
// Capture relationship nodes
|
||||
std::vector<express::Entity> relationships;
|
||||
std::vector<express::entity> relationships;
|
||||
auto IfcRelDefinesByProperties = f.schema()->declaration_by_name("IfcRelDefinesByProperties");
|
||||
|
||||
for (auto& eq : element_quantities) {
|
||||
@@ -1385,14 +1380,14 @@ void fix_quantities(ifcopenshell::file& f, bool no_progress, bool quiet, bool st
|
||||
}
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::Settings settings;
|
||||
settings.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = false;
|
||||
settings.get<ifcopenshell::geometry::settings::WeldVertices>().value = false;
|
||||
settings.get<ifcopenshell::geometry::settings::ReorientShells>().value = true;
|
||||
settings.get<ifcopenshell::geometry::settings::ConvertBackUnits>().value = true;
|
||||
settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
|
||||
ifcopenshell::geom::settings settings;
|
||||
settings.get<ifcopenshell::geom::settings::UseWorldCoords>().value = false;
|
||||
settings.get<ifcopenshell::geom::settings::WeldVertices>().value = false;
|
||||
settings.get<ifcopenshell::geom::settings::ReorientShells>().value = true;
|
||||
settings.get<ifcopenshell::geom::settings::ConvertBackUnits>().value = true;
|
||||
settings.get<ifcopenshell::geom::settings::IteratorOutput>().value = ifcopenshell::geom::settings::NATIVE;
|
||||
|
||||
IfcGeom::Iterator context_iterator(ifcopenshell::geometry::kernels::construct(&f, "opencascade", settings), settings, &f, {}, 1, logger);
|
||||
ifcopenshell::geom::iterator context_iterator(ifcopenshell::geom::kernels::construct(&f, "opencascade", settings), settings, &f, {}, 1, logger);
|
||||
|
||||
if (!context_iterator.initialize()) {
|
||||
return;
|
||||
@@ -1424,16 +1419,16 @@ void fix_quantities(ifcopenshell::file& f, bool no_progress, bool quiet, bool st
|
||||
latebound_access::set(ownerhist, "ChangeAction", std::string("MODIFIED"));
|
||||
latebound_access::set(ownerhist, "CreationDate", (int64_t)time(0));
|
||||
|
||||
express::Base quantity;
|
||||
std::vector<express::Base> objects;
|
||||
boost::shared_ptr<IfcGeom::Representation::BRep> previous_geometry_pointer;
|
||||
express::base quantity;
|
||||
std::vector<express::base> objects;
|
||||
boost::shared_ptr<ifcopenshell::geom::Representation::brep> previous_geometry_pointer;
|
||||
|
||||
for (;; ++num_created) {
|
||||
bool has_more = true;
|
||||
if (num_created) {
|
||||
has_more = context_iterator.next();
|
||||
}
|
||||
IfcGeom::BRepElement* geom_object = nullptr;
|
||||
ifcopenshell::geom::brep_element* geom_object = nullptr;
|
||||
if (has_more) {
|
||||
geom_object = context_iterator.get_native();
|
||||
}
|
||||
@@ -1453,7 +1448,7 @@ void fix_quantities(ifcopenshell::file& f, bool no_progress, bool quiet, bool st
|
||||
break;
|
||||
}
|
||||
|
||||
std::vector<express::Base> quantities;
|
||||
std::vector<express::base> quantities;
|
||||
|
||||
double a, b, c;
|
||||
if (geom_object->geometry().calculate_surface_area(a)) {
|
||||
@@ -1481,7 +1476,7 @@ void fix_quantities(ifcopenshell::file& f, bool no_progress, bool quiet, bool st
|
||||
latebound_access::set(quantity_complex, "Name", std::string("Shape Validation Properties"));
|
||||
quantities.push_back(quantity_complex);
|
||||
|
||||
std::vector<express::Base> quantities_2;
|
||||
std::vector<express::base> quantities_2;
|
||||
|
||||
for (auto& part : geom_object->geometry()) {
|
||||
auto quantity_count = latebound_access::create(f, "IfcQuantityCount");
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include "validation_utils.h"
|
||||
|
||||
using namespace ifcopenshell::geometry;
|
||||
using namespace ifcopenshell::geom;
|
||||
|
||||
#include <CGAL/AABB_tree.h>
|
||||
#include <CGAL/AABB_traits.h>
|
||||
@@ -45,16 +45,16 @@ void fix_spaceboundaries(ifcopenshell::file& f, bool no_progress, bool quiet, bo
|
||||
return;
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::Settings settings;
|
||||
ifcopenshell::geom::settings settings;
|
||||
|
||||
settings.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = false;
|
||||
settings.get<ifcopenshell::geometry::settings::WeldVertices>().value = false;
|
||||
settings.get<ifcopenshell::geometry::settings::ReorientShells>().value = true;
|
||||
settings.get<ifcopenshell::geometry::settings::ConvertBackUnits>().value = true;
|
||||
settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
|
||||
settings.get<ifcopenshell::geometry::settings::DisableOpeningSubtractions>().value = true;
|
||||
settings.get<ifcopenshell::geom::settings::UseWorldCoords>().value = false;
|
||||
settings.get<ifcopenshell::geom::settings::WeldVertices>().value = false;
|
||||
settings.get<ifcopenshell::geom::settings::ReorientShells>().value = true;
|
||||
settings.get<ifcopenshell::geom::settings::ConvertBackUnits>().value = true;
|
||||
settings.get<ifcopenshell::geom::settings::IteratorOutput>().value = ifcopenshell::geom::settings::NATIVE;
|
||||
settings.get<ifcopenshell::geom::settings::DisableOpeningSubtractions>().value = true;
|
||||
|
||||
ifcopenshell::geometry::Converter c(ifcopenshell::geometry::kernels::construct(&f2, "cgal", settings), &f2, settings, logger);
|
||||
ifcopenshell::geom::converter c(ifcopenshell::geom::kernels::construct(&f2, "cgal", settings), &f2, settings, logger);
|
||||
|
||||
std::map<std::set<std::string>, std::vector<Kernel_::Point_3>> elem_to_space_boundary_coords;
|
||||
|
||||
|
||||
@@ -10,20 +10,20 @@
|
||||
#include <algorithm>
|
||||
|
||||
void fix_storeycontainment(ifcopenshell::file& f, bool no_progress, bool quiet, bool stderr_progress, logger& logger = ::logger::root()) {
|
||||
ifcopenshell::geometry::Settings settings;
|
||||
ifcopenshell::geom::settings settings;
|
||||
|
||||
settings.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = false;
|
||||
settings.get<ifcopenshell::geometry::settings::WeldVertices>().value = false;
|
||||
settings.get<ifcopenshell::geometry::settings::ReorientShells>().value = true;
|
||||
settings.get<ifcopenshell::geometry::settings::ConvertBackUnits>().value = true;
|
||||
settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
|
||||
settings.get<ifcopenshell::geometry::settings::DisableOpeningSubtractions>().value = true;
|
||||
settings.get<ifcopenshell::geom::settings::UseWorldCoords>().value = false;
|
||||
settings.get<ifcopenshell::geom::settings::WeldVertices>().value = false;
|
||||
settings.get<ifcopenshell::geom::settings::ReorientShells>().value = true;
|
||||
settings.get<ifcopenshell::geom::settings::ConvertBackUnits>().value = true;
|
||||
settings.get<ifcopenshell::geom::settings::IteratorOutput>().value = ifcopenshell::geom::settings::NATIVE;
|
||||
settings.get<ifcopenshell::geom::settings::DisableOpeningSubtractions>().value = true;
|
||||
|
||||
std::vector<ifcopenshell::geometry::filter_t> no_openings_and_spaces = {
|
||||
IfcGeom::entity_filter(false, false, {"IfcOpeningElement", "IfcSpace"})
|
||||
std::vector<ifcopenshell::geom::filter_t> no_openings_and_spaces = {
|
||||
ifcopenshell::geom::entity_filter(false, false, {"IfcOpeningElement", "IfcSpace"})
|
||||
};
|
||||
|
||||
IfcGeom::Iterator context_iterator(ifcopenshell::geometry::kernels::construct(&f, "cgal", settings), settings, &f, no_openings_and_spaces, 1, logger);
|
||||
ifcopenshell::geom::iterator context_iterator(ifcopenshell::geom::kernels::construct(&f, "cgal", settings), settings, &f, no_openings_and_spaces, 1, logger);
|
||||
|
||||
auto get_elevation = [](const ifcopenshell::IfcBaseClass* a) {
|
||||
return ((const ifcopenshell::IfcBaseEntity*)a)->get_value<double>("Elevation", 0.);
|
||||
@@ -81,13 +81,13 @@ void fix_storeycontainment(ifcopenshell::file& f, bool no_progress, bool quiet,
|
||||
// std::wcout << p.first << " - " << p.second << std::endl;
|
||||
Kernel_::Point_3 p1(-LARGE, -LARGE, p.first);
|
||||
Kernel_::Point_3 p2(+LARGE, +LARGE, p.second);
|
||||
auto poly = ifcopenshell::geometry::utils::create_cube(p1, p2);
|
||||
return ifcopenshell::geometry::utils::create_nef_polyhedron(poly);
|
||||
auto poly = ifcopenshell::geom::utils::create_cube(p1, p2);
|
||||
return ifcopenshell::geom::utils::create_nef_polyhedron(poly);
|
||||
});
|
||||
|
||||
/*
|
||||
for (auto& n : nefs) {
|
||||
auto poly = ifcopenshell::geometry::utils::create_polyhedron(n);
|
||||
auto poly = ifcopenshell::geom::utils::create_polyhedron(n);
|
||||
auto bounds = CGAL::Polygon_mesh_processing::bbox_3(poly);
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
std::wcout << bounds.min(i) << std::endl;
|
||||
@@ -111,7 +111,7 @@ void fix_storeycontainment(ifcopenshell::file& f, bool no_progress, bool quiet,
|
||||
if (num_created) {
|
||||
has_more = context_iterator.next();
|
||||
}
|
||||
IfcGeom::BRepElement* geom_object = nullptr;
|
||||
ifcopenshell::geom::brep_element* geom_object = nullptr;
|
||||
if (has_more) {
|
||||
geom_object = context_iterator.get_native();
|
||||
}
|
||||
@@ -134,7 +134,7 @@ void fix_storeycontainment(ifcopenshell::file& f, bool no_progress, bool quiet,
|
||||
std::vector<double> intersection_volumes(nefs.size());
|
||||
|
||||
for (auto& g : geom_object->geometry()) {
|
||||
auto s = std::static_pointer_cast<ifcopenshell::geometry::CgalShape>(g.Shape())->poly();
|
||||
auto s = std::static_pointer_cast<ifcopenshell::geom::cgal_shape>(g.Shape())->poly();
|
||||
const auto& m = g.Placement()->ccomponents();
|
||||
const auto& n = geom_object->transformation().data()->ccomponents();
|
||||
|
||||
@@ -166,7 +166,7 @@ void fix_storeycontainment(ifcopenshell::file& f, bool no_progress, bool quiet,
|
||||
}
|
||||
*/
|
||||
|
||||
CGAL::Nef_polyhedron_3<Kernel_> part_nef = ifcopenshell::geometry::utils::create_nef_polyhedron(s);
|
||||
CGAL::Nef_polyhedron_3<Kernel_> part_nef = ifcopenshell::geom::utils::create_nef_polyhedron(s);
|
||||
|
||||
if (!part_nef.is_simple()) {
|
||||
// std::wcout << "not simple" << std::endl;
|
||||
@@ -175,7 +175,7 @@ void fix_storeycontainment(ifcopenshell::file& f, bool no_progress, bool quiet,
|
||||
|
||||
std::vector<double>::iterator accumulator = intersection_volumes.begin();
|
||||
std::for_each(nefs.begin(), nefs.end(), [&accumulator, &part_nef](const CGAL::Nef_polyhedron_3<Kernel_>& storey_nef) {
|
||||
auto poly = ifcopenshell::geometry::utils::create_polyhedron(part_nef * storey_nef);
|
||||
auto poly = ifcopenshell::geom::utils::create_polyhedron(part_nef * storey_nef);
|
||||
CGAL::Polygon_mesh_processing::triangulate_faces(poly);
|
||||
*accumulator += CGAL::to_double(CGAL::Polygon_mesh_processing::volume(poly));
|
||||
accumulator++;
|
||||
|
||||
@@ -7,24 +7,23 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace ifcopenshell::geometry;
|
||||
using namespace ifcopenshell::geom;
|
||||
|
||||
void fix_wallconnectivity(ifcopenshell::file& f, bool no_progress, bool quiet, bool stderr_progress, logger& logger = ::logger::root()) {
|
||||
intersection_validator v(f, { "IfcWall" }, 1.e-3, no_progress, quiet, stderr_progress, logger);
|
||||
|
||||
ifcopenshell::geometry::Settings settings;
|
||||
ifcopenshell::geom::settings settings;
|
||||
|
||||
settings.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = false;
|
||||
settings.get<ifcopenshell::geometry::settings::WeldVertices>().value = false;
|
||||
settings.get<ifcopenshell::geometry::settings::ReorientShells>().value = true;
|
||||
settings.get<ifcopenshell::geometry::settings::ConvertBackUnits>().value = true;
|
||||
settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
|
||||
settings.get<ifcopenshell::geometry::settings::DisableOpeningSubtractions>().value = true;
|
||||
settings.get<ifcopenshell::geom::settings::UseWorldCoords>().value = false;
|
||||
settings.get<ifcopenshell::geom::settings::WeldVertices>().value = false;
|
||||
settings.get<ifcopenshell::geom::settings::ReorientShells>().value = true;
|
||||
settings.get<ifcopenshell::geom::settings::ConvertBackUnits>().value = true;
|
||||
settings.get<ifcopenshell::geom::settings::IteratorOutput>().value = ifcopenshell::geom::settings::NATIVE;
|
||||
settings.get<ifcopenshell::geom::settings::DisableOpeningSubtractions>().value = true;
|
||||
|
||||
settings.get<ifcopenshell::geometry::settings::IncludeCurves>().value = true;
|
||||
settings.get<ifcopenshell::geometry::settings::IncludeSurfaces>().value = false;
|
||||
settings.get<ifcopenshell::geom::settings::OutputDimensionality>().value = ifcopenshell::geom::settings::CURVES;
|
||||
|
||||
ifcopenshell::geometry::Converter c(ifcopenshell::geometry::kernels::construct(&f, "cgal", settings), &f, settings, logger);
|
||||
ifcopenshell::geom::converter c(ifcopenshell::geom::kernels::construct(&f, "cgal", settings), &f, settings, logger);
|
||||
|
||||
auto rels = f.instances_by_type("IfcRelConnectsPathElements");
|
||||
std::map<std::set<const ifcopenshell::IfcBaseClass*>, const ifcopenshell::IfcBaseClass*> rel_by_elem;
|
||||
@@ -58,8 +57,8 @@ void fix_wallconnectivity(ifcopenshell::file& f, bool no_progress, bool quiet, b
|
||||
}
|
||||
|
||||
#if 0
|
||||
auto a_poly = ifcopenshell::geometry::utils::create_polyhedron(a.handle()->second);
|
||||
auto b_poly = ifcopenshell::geometry::utils::create_polyhedron(b.handle()->second);
|
||||
auto a_poly = ifcopenshell::geom::utils::create_polyhedron(a.handle()->second);
|
||||
auto b_poly = ifcopenshell::geom::utils::create_polyhedron(b.handle()->second);
|
||||
|
||||
std::wcout << "a" << std::endl;
|
||||
for (auto& v : vertices(a_poly)) {
|
||||
|
||||
@@ -448,26 +448,26 @@ struct intersection_validator {
|
||||
|
||||
intersection_validator(ifcopenshell::file& f, std::initializer_list<std::string> entities, double eps, bool no_progress, bool quiet, bool stderr_progress, logger& logger = ::logger::root()) {
|
||||
|
||||
ifcopenshell::geometry::Settings settings;
|
||||
settings.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = false;
|
||||
settings.get<ifcopenshell::geometry::settings::WeldVertices>().value = false;
|
||||
settings.get<ifcopenshell::geometry::settings::ReorientShells>().value = true;
|
||||
settings.get<ifcopenshell::geometry::settings::ConvertBackUnits>().value = true;
|
||||
settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
|
||||
settings.get<ifcopenshell::geometry::settings::DisableOpeningSubtractions>().value = true;
|
||||
ifcopenshell::geom::settings settings;
|
||||
settings.get<ifcopenshell::geom::settings::UseWorldCoords>().value = false;
|
||||
settings.get<ifcopenshell::geom::settings::WeldVertices>().value = false;
|
||||
settings.get<ifcopenshell::geom::settings::ReorientShells>().value = true;
|
||||
settings.get<ifcopenshell::geom::settings::ConvertBackUnits>().value = true;
|
||||
settings.get<ifcopenshell::geom::settings::IteratorOutput>().value = ifcopenshell::geom::settings::NATIVE;
|
||||
settings.get<ifcopenshell::geom::settings::DisableOpeningSubtractions>().value = true;
|
||||
|
||||
std::vector<ifcopenshell::geometry::filter_t> spaces_and_walls = {
|
||||
IfcGeom::entity_filter(true, false, entities)
|
||||
std::vector<ifcopenshell::geom::filter_t> spaces_and_walls = {
|
||||
ifcopenshell::geom::entity_filter(true, false, entities)
|
||||
};
|
||||
|
||||
IfcGeom::Iterator context_iterator(ifcopenshell::geometry::kernels::construct(&f, "cgal", settings), settings, &f, spaces_and_walls, 1, logger);
|
||||
ifcopenshell::geom::iterator context_iterator(ifcopenshell::geom::kernels::construct(&f, "cgal", settings), settings, &f, spaces_and_walls, 1, logger);
|
||||
|
||||
if (!context_iterator.initialize()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto polycube = ifcopenshell::geometry::utils::create_cube(eps);
|
||||
auto cube = ifcopenshell::geometry::utils::create_nef_polyhedron(polycube);
|
||||
auto polycube = ifcopenshell::geom::utils::create_cube(eps);
|
||||
auto cube = ifcopenshell::geom::utils::create_nef_polyhedron(polycube);
|
||||
|
||||
size_t num_created = 0;
|
||||
int old_progress = quiet ? 0 : -1;
|
||||
@@ -477,7 +477,7 @@ struct intersection_validator {
|
||||
if (num_created) {
|
||||
has_more = context_iterator.next();
|
||||
}
|
||||
IfcGeom::BRepElement* geom_object = nullptr;
|
||||
ifcopenshell::geom::brep_element* geom_object = nullptr;
|
||||
if (has_more) {
|
||||
geom_object = context_iterator.get_native();
|
||||
}
|
||||
@@ -491,7 +491,7 @@ struct intersection_validator {
|
||||
std::wcout << sss.c_str() << std::endl;
|
||||
|
||||
for (auto& g : geom_object->geometry()) {
|
||||
cgal_shape_t s = *std::static_pointer_cast<ifcopenshell::geometry::CgalShape>(g.Shape());
|
||||
cgal_shape_t s = *std::static_pointer_cast<ifcopenshell::geom::cgal_shape>(g.Shape());
|
||||
const auto& m = g.Placement()->ccomponents();
|
||||
const auto& n = geom_object->transformation().data()->ccomponents();
|
||||
|
||||
@@ -511,7 +511,7 @@ struct intersection_validator {
|
||||
}
|
||||
|
||||
std::clock_t nef_begin = std::clock();
|
||||
CGAL::Nef_polyhedron_3<Kernel_> nef = ifcopenshell::geometry::utils::create_nef_polyhedron(s);
|
||||
CGAL::Nef_polyhedron_3<Kernel_> nef = ifcopenshell::geom::utils::create_nef_polyhedron(s);
|
||||
std::clock_t nef_end = std::clock();
|
||||
total_nef_time += (nef_end - nef_begin) / (double) CLOCKS_PER_SEC;
|
||||
if (nef.is_empty()) {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#include "AbstractKernel.h"
|
||||
|
||||
using namespace ifcopenshell::geometry;
|
||||
using namespace ifcopenshell::geom;
|
||||
|
||||
const char* ifcopenshell::not_implemented_error::what() const noexcept {
|
||||
return "Not implemented.";
|
||||
@@ -15,7 +15,7 @@ const char* ifcopenshell::not_supported_error::what() const noexcept {
|
||||
return "Not supported.";
|
||||
}
|
||||
|
||||
bool ifcopenshell::geometry::kernels::AbstractKernel::convert(const taxonomy::ptr item, IfcGeom::ConversionResults& results) {
|
||||
bool ifcopenshell::geom::kernels::abstract_kernel::convert(const taxonomy::ptr item, ifcopenshell::geom::conversion_results& results) {
|
||||
if (settings_.get<settings::CacheShapes>().get()) {
|
||||
auto it = cache_.find(item);
|
||||
if (it != cache_.end()) {
|
||||
@@ -62,12 +62,12 @@ bool ifcopenshell::geometry::kernels::AbstractKernel::convert(const taxonomy::pt
|
||||
return res;
|
||||
}
|
||||
|
||||
const Settings& ifcopenshell::geometry::kernels::AbstractKernel::settings() const
|
||||
const ifcopenshell::geom::settings& ifcopenshell::geom::kernels::abstract_kernel::settings() const
|
||||
{
|
||||
return settings_;
|
||||
}
|
||||
|
||||
bool ifcopenshell::geometry::kernels::AbstractKernel::convert_impl(const taxonomy::collection::ptr collection, IfcGeom::ConversionResults& r) {
|
||||
bool ifcopenshell::geom::kernels::abstract_kernel::convert_impl(const taxonomy::collection::ptr collection, ifcopenshell::geom::conversion_results& r) {
|
||||
auto s = r.size();
|
||||
for (auto& c : collection->children) {
|
||||
if (!convert(c, r) && !partial_success_is_success) {
|
||||
@@ -85,42 +85,42 @@ bool ifcopenshell::geometry::kernels::AbstractKernel::convert_impl(const taxonom
|
||||
return r.size() > s;
|
||||
}
|
||||
|
||||
bool ifcopenshell::geometry::kernels::AbstractKernel::convert_impl(const taxonomy::function_item::ptr item, IfcGeom::ConversionResults& cs) {
|
||||
bool ifcopenshell::geom::kernels::abstract_kernel::convert_impl(const taxonomy::function_item::ptr item, ifcopenshell::geom::conversion_results& cs) {
|
||||
function_item_evaluator evaluator(settings(),item);
|
||||
auto expl = evaluator.evaluate();
|
||||
expl->instance = item->instance;
|
||||
return convert(expl, cs);
|
||||
}
|
||||
|
||||
bool ifcopenshell::geometry::kernels::AbstractKernel::convert_impl(const taxonomy::functor_item::ptr item, IfcGeom::ConversionResults& cs) {
|
||||
bool ifcopenshell::geom::kernels::abstract_kernel::convert_impl(const taxonomy::functor_item::ptr item, ifcopenshell::geom::conversion_results& cs) {
|
||||
function_item_evaluator evaluator(settings(), item);
|
||||
auto expl = evaluator.evaluate();
|
||||
expl->instance = item->instance;
|
||||
return convert(expl, cs);
|
||||
}
|
||||
|
||||
bool ifcopenshell::geometry::kernels::AbstractKernel::convert_impl(const taxonomy::piecewise_function::ptr item, IfcGeom::ConversionResults& cs) {
|
||||
bool ifcopenshell::geom::kernels::abstract_kernel::convert_impl(const taxonomy::piecewise_function::ptr item, ifcopenshell::geom::conversion_results& cs) {
|
||||
function_item_evaluator evaluator(settings(), item);
|
||||
auto expl = evaluator.evaluate();
|
||||
expl->instance = item->instance;
|
||||
return convert(expl, cs);
|
||||
}
|
||||
|
||||
bool ifcopenshell::geometry::kernels::AbstractKernel::convert_impl(const taxonomy::gradient_function::ptr item, IfcGeom::ConversionResults& cs) {
|
||||
bool ifcopenshell::geom::kernels::abstract_kernel::convert_impl(const taxonomy::gradient_function::ptr item, ifcopenshell::geom::conversion_results& cs) {
|
||||
function_item_evaluator evaluator(settings(), item);
|
||||
auto expl = evaluator.evaluate();
|
||||
expl->instance = item->instance;
|
||||
return convert(expl, cs);
|
||||
}
|
||||
|
||||
bool ifcopenshell::geometry::kernels::AbstractKernel::convert_impl(const taxonomy::cant_function::ptr item, IfcGeom::ConversionResults& cs) {
|
||||
bool ifcopenshell::geom::kernels::abstract_kernel::convert_impl(const taxonomy::cant_function::ptr item, ifcopenshell::geom::conversion_results& cs) {
|
||||
function_item_evaluator evaluator(settings(), item);
|
||||
auto expl = evaluator.evaluate();
|
||||
expl->instance = item->instance;
|
||||
return convert(expl, cs);
|
||||
}
|
||||
|
||||
bool ifcopenshell::geometry::kernels::AbstractKernel::convert_impl(const taxonomy::offset_function::ptr item, IfcGeom::ConversionResults& cs) {
|
||||
bool ifcopenshell::geom::kernels::abstract_kernel::convert_impl(const taxonomy::offset_function::ptr item, ifcopenshell::geom::conversion_results& cs) {
|
||||
function_item_evaluator evaluator(settings(), item);
|
||||
auto expl = evaluator.evaluate();
|
||||
expl->instance = item->instance;
|
||||
|
||||
@@ -58,86 +58,86 @@ namespace ifcopenshell {
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
namespace geometry { namespace kernels {
|
||||
namespace geom { namespace kernels {
|
||||
|
||||
class IFC_GEOM_API AbstractKernel {
|
||||
class IFC_GEOM_API abstract_kernel {
|
||||
private:
|
||||
std::unordered_map<taxonomy::item::ptr, IfcGeom::ConversionResults, ifcopenshell::geometry::taxonomy::hash_functor, ifcopenshell::geometry::taxonomy::equal_functor> cache_;
|
||||
std::unordered_map<taxonomy::item::ptr, ifcopenshell::geom::conversion_results, ifcopenshell::geom::taxonomy::hash_functor, ifcopenshell::geom::taxonomy::equal_functor> cache_;
|
||||
protected:
|
||||
std::string geometry_library_;
|
||||
Settings settings_;
|
||||
ifcopenshell::geom::settings settings_;
|
||||
::logger& logger_;
|
||||
public:
|
||||
bool propagate_exceptions = false;
|
||||
bool partial_success_is_success = true;
|
||||
|
||||
AbstractKernel(const std::string& geometry_library, const Settings& settings, ::logger& logger = ::logger::root())
|
||||
abstract_kernel(const std::string& geometry_library, const ifcopenshell::geom::settings& settings, ::logger& logger = ::logger::root())
|
||||
: geometry_library_(geometry_library)
|
||||
, settings_(settings)
|
||||
, logger_(logger) {}
|
||||
|
||||
virtual ~AbstractKernel() = default;
|
||||
virtual ~abstract_kernel() = default;
|
||||
|
||||
virtual bool convert(const taxonomy::ptr, IfcGeom::ConversionResults&);
|
||||
const Settings& settings() const;
|
||||
virtual bool convert(const taxonomy::ptr, ifcopenshell::geom::conversion_results&);
|
||||
const ifcopenshell::geom::settings& settings() const;
|
||||
const std::string& geometry_library() const {
|
||||
return geometry_library_;
|
||||
}
|
||||
virtual std::string_view backend_id() const {
|
||||
return geometry_library_;
|
||||
}
|
||||
virtual bool accepts(const IfcGeom::ConversionResultShape& shape) const {
|
||||
virtual bool accepts(const ifcopenshell::geom::conversion_result_shape& shape) const {
|
||||
return shape.backend_id() == backend_id();
|
||||
}
|
||||
::logger& logger() const { return logger_; }
|
||||
|
||||
virtual bool supports_boolean_operations() const = 0;
|
||||
|
||||
virtual bool convert_impl(const taxonomy::matrix4::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::point3::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::direction3::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::line::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::circle::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::ellipse::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::bspline_curve::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::edge::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::loop::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::shell::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::face::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::extrusion::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::node::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::colour::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::boolean_result::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::plane::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::offset_curve::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::revolve::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::bspline_surface::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::cylinder::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::sphere::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::torus::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::solid::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::sweep_along_curve::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::loft::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::collection::ptr, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const taxonomy::function_item::ptr item, IfcGeom::ConversionResults& cs);
|
||||
virtual bool convert_impl(const taxonomy::functor_item::ptr item, IfcGeom::ConversionResults& cs);
|
||||
virtual bool convert_impl(const taxonomy::piecewise_function::ptr item, IfcGeom::ConversionResults& cs);
|
||||
virtual bool convert_impl(const taxonomy::gradient_function::ptr item, IfcGeom::ConversionResults& cs);
|
||||
virtual bool convert_impl(const taxonomy::cant_function::ptr item, IfcGeom::ConversionResults& cs);
|
||||
virtual bool convert_impl(const taxonomy::offset_function::ptr item, IfcGeom::ConversionResults& cs);
|
||||
virtual bool convert_impl(const taxonomy::matrix4::ptr, ifcopenshell::geom::conversion_results&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::point3::ptr, ifcopenshell::geom::conversion_results&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::direction3::ptr, ifcopenshell::geom::conversion_results&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::line::ptr, ifcopenshell::geom::conversion_results&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::circle::ptr, ifcopenshell::geom::conversion_results&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::ellipse::ptr, ifcopenshell::geom::conversion_results&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::bspline_curve::ptr, ifcopenshell::geom::conversion_results&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::edge::ptr, ifcopenshell::geom::conversion_results&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::loop::ptr, ifcopenshell::geom::conversion_results&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::shell::ptr, ifcopenshell::geom::conversion_results&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::face::ptr, ifcopenshell::geom::conversion_results&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::extrusion::ptr, ifcopenshell::geom::conversion_results&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::node::ptr, ifcopenshell::geom::conversion_results&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::colour::ptr, ifcopenshell::geom::conversion_results&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::boolean_result::ptr, ifcopenshell::geom::conversion_results&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::plane::ptr, ifcopenshell::geom::conversion_results&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::offset_curve::ptr, ifcopenshell::geom::conversion_results&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::revolve::ptr, ifcopenshell::geom::conversion_results&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::bspline_surface::ptr, ifcopenshell::geom::conversion_results&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::cylinder::ptr, ifcopenshell::geom::conversion_results&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::sphere::ptr, ifcopenshell::geom::conversion_results&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::torus::ptr, ifcopenshell::geom::conversion_results&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::solid::ptr, ifcopenshell::geom::conversion_results&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::sweep_along_curve::ptr, ifcopenshell::geom::conversion_results&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::loft::ptr, ifcopenshell::geom::conversion_results&) { throw not_implemented_error(); }
|
||||
virtual bool convert_impl(const taxonomy::collection::ptr, ifcopenshell::geom::conversion_results&);
|
||||
virtual bool convert_impl(const taxonomy::function_item::ptr item, ifcopenshell::geom::conversion_results& cs);
|
||||
virtual bool convert_impl(const taxonomy::functor_item::ptr item, ifcopenshell::geom::conversion_results& cs);
|
||||
virtual bool convert_impl(const taxonomy::piecewise_function::ptr item, ifcopenshell::geom::conversion_results& cs);
|
||||
virtual bool convert_impl(const taxonomy::gradient_function::ptr item, ifcopenshell::geom::conversion_results& cs);
|
||||
virtual bool convert_impl(const taxonomy::cant_function::ptr item, ifcopenshell::geom::conversion_results& cs);
|
||||
virtual bool convert_impl(const taxonomy::offset_function::ptr item, ifcopenshell::geom::conversion_results& cs);
|
||||
|
||||
/*
|
||||
virtual void set_offset(const std::array<double, 3> &p_offset);
|
||||
virtual void set_rotation(const std::array<double, 4> &p_rotation);
|
||||
*/
|
||||
|
||||
virtual bool apply_layerset(IfcGeom::ConversionResults&, const ifcopenshell::geometry::layerset_information&) { throw not_implemented_error(); }
|
||||
virtual bool apply_folded_layerset(IfcGeom::ConversionResults&, const ifcopenshell::geometry::layerset_information&, const std::map<express::Base, ifcopenshell::geometry::layerset_information>&) { throw not_implemented_error(); }
|
||||
virtual bool convert_openings(const express::Base& entity, const std::vector<std::pair<taxonomy::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
|
||||
const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes) = 0;
|
||||
virtual bool unify_shapes(const IfcGeom::ConversionResults&, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
virtual bool apply_layerset(ifcopenshell::geom::conversion_results&, const ifcopenshell::geom::layerset_information&) { throw not_implemented_error(); }
|
||||
virtual bool apply_folded_layerset(ifcopenshell::geom::conversion_results&, const ifcopenshell::geom::layerset_information&, const std::map<express::base, ifcopenshell::geom::layerset_information>&) { throw not_implemented_error(); }
|
||||
virtual bool convert_openings(const express::base& entity, const std::vector<std::pair<taxonomy::ptr, ifcopenshell::geom::taxonomy::matrix4>>& openings,
|
||||
const ifcopenshell::geom::conversion_results& entity_shapes, const ifcopenshell::geom::taxonomy::matrix4& entity_trsf, ifcopenshell::geom::conversion_results& cut_shapes) = 0;
|
||||
virtual bool unify_shapes(const ifcopenshell::geom::conversion_results&, ifcopenshell::geom::conversion_results&) { throw not_implemented_error(); }
|
||||
|
||||
virtual AbstractKernel* clone(::logger& logger) const = 0;
|
||||
virtual abstract_kernel* clone(::logger& logger) const = 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -148,9 +148,9 @@ namespace {
|
||||
/* A compile-time for loop over the taxonomy kinds */
|
||||
template <size_t N>
|
||||
struct dispatch_conversion {
|
||||
static bool dispatch(ifcopenshell::geometry::kernels::AbstractKernel* kernel, ifcopenshell::geometry::taxonomy::kinds item_kind, const ifcopenshell::geometry::taxonomy::ptr& item, IfcGeom::ConversionResults& results) {
|
||||
static bool dispatch(ifcopenshell::geom::kernels::abstract_kernel* kernel, ifcopenshell::geom::taxonomy::kinds item_kind, const ifcopenshell::geom::taxonomy::ptr& item, ifcopenshell::geom::conversion_results& results) {
|
||||
if (N == item_kind) {
|
||||
auto concrete_item = std::static_pointer_cast<ifcopenshell::geometry::taxonomy::type_by_kind::type<N>>(item);
|
||||
auto concrete_item = std::static_pointer_cast<ifcopenshell::geom::taxonomy::type_by_kind::type<N>>(item);
|
||||
return kernel->convert_impl(concrete_item, results);
|
||||
} else {
|
||||
return dispatch_conversion<N + 1>::dispatch(kernel, item_kind, item, results);
|
||||
@@ -159,14 +159,14 @@ namespace {
|
||||
};
|
||||
|
||||
template <>
|
||||
struct dispatch_conversion<ifcopenshell::geometry::taxonomy::type_by_kind::max> {
|
||||
static bool dispatch(ifcopenshell::geometry::kernels::AbstractKernel* kernel, ifcopenshell::geometry::taxonomy::kinds, const ifcopenshell::geometry::taxonomy::ptr& item, IfcGeom::ConversionResults&) {
|
||||
struct dispatch_conversion<ifcopenshell::geom::taxonomy::type_by_kind::max> {
|
||||
static bool dispatch(ifcopenshell::geom::kernels::abstract_kernel* kernel, ifcopenshell::geom::taxonomy::kinds, const ifcopenshell::geom::taxonomy::ptr& item, ifcopenshell::geom::conversion_results&) {
|
||||
if (kernel->partial_success_is_success) {
|
||||
std::string created_from;
|
||||
if (item->instance) {
|
||||
created_from = " (created from " + item->instance.declaration().name() + ")";
|
||||
}
|
||||
kernel->logger().error("UNS", 1, "No support for " + ifcopenshell::geometry::taxonomy::kind_to_string(item->kind()) + created_from + " in kernel " + kernel->geometry_library());
|
||||
kernel->logger().error("UNS", 1, "No support for " + ifcopenshell::geom::taxonomy::kind_to_string(item->kind()) + created_from + " in kernel " + kernel->geometry_library());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -174,8 +174,8 @@ namespace {
|
||||
|
||||
template <size_t N>
|
||||
struct dispatch_with_upgrade {
|
||||
static bool dispatch(ifcopenshell::geometry::kernels::AbstractKernel* kernel, const ifcopenshell::geometry::taxonomy::ptr& item, IfcGeom::ConversionResults& results) {
|
||||
auto concrete_item = ifcopenshell::geometry::taxonomy::template dcast<ifcopenshell::geometry::taxonomy::upgrades::type<N>>(item);
|
||||
static bool dispatch(ifcopenshell::geom::kernels::abstract_kernel* kernel, const ifcopenshell::geom::taxonomy::ptr& item, ifcopenshell::geom::conversion_results& results) {
|
||||
auto concrete_item = ifcopenshell::geom::taxonomy::template dcast<ifcopenshell::geom::taxonomy::upgrades::type<N>>(item);
|
||||
if (concrete_item) {
|
||||
return kernel->convert_impl(concrete_item, results);
|
||||
} else {
|
||||
@@ -185,39 +185,39 @@ namespace {
|
||||
};
|
||||
|
||||
template <>
|
||||
struct dispatch_with_upgrade<ifcopenshell::geometry::taxonomy::upgrades::max> {
|
||||
static bool dispatch(ifcopenshell::geometry::kernels::AbstractKernel* kernel, const ifcopenshell::geometry::taxonomy::ptr& item, IfcGeom::ConversionResults&) {
|
||||
struct dispatch_with_upgrade<ifcopenshell::geom::taxonomy::upgrades::max> {
|
||||
static bool dispatch(ifcopenshell::geom::kernels::abstract_kernel* kernel, const ifcopenshell::geom::taxonomy::ptr& item, ifcopenshell::geom::conversion_results&) {
|
||||
if (kernel->partial_success_is_success) {
|
||||
std::string created_from;
|
||||
if (item->instance) {
|
||||
created_from = " (created from " + item->instance.declaration().name() + ")";
|
||||
}
|
||||
kernel->logger().error("UNS", 2, "No support (after considering item upgrade) for " + ifcopenshell::geometry::taxonomy::kind_to_string(item->kind()) + created_from + " in kernel " + kernel->geometry_library());
|
||||
kernel->logger().error("UNS", 2, "No support (after considering item upgrade) for " + ifcopenshell::geom::taxonomy::kind_to_string(item->kind()) + created_from + " in kernel " + kernel->geometry_library());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class Tuple>
|
||||
struct TupleTypeIndex;
|
||||
struct tuple_type_index;
|
||||
|
||||
template <class T, class... Types>
|
||||
struct TupleTypeIndex<T, std::tuple<T, Types...>> {
|
||||
struct tuple_type_index<T, std::tuple<T, Types...>> {
|
||||
static const std::size_t value = 0;
|
||||
};
|
||||
|
||||
template <class T, class U, class... Types>
|
||||
struct TupleTypeIndex<T, std::tuple<U, Types...>> {
|
||||
static const std::size_t value = 1 + TupleTypeIndex<T, std::tuple<Types...>>::value;
|
||||
struct tuple_type_index<T, std::tuple<U, Types...>> {
|
||||
static const std::size_t value = 1 + tuple_type_index<T, std::tuple<Types...>>::value;
|
||||
};
|
||||
|
||||
/* A compile-time for loop over the curve kinds */
|
||||
template <typename T, size_t N = 0>
|
||||
struct dispatch_curve_creation {
|
||||
static bool dispatch(const ifcopenshell::geometry::taxonomy::ptr& item, T& visitor) {
|
||||
constexpr auto KindIndex = TupleTypeIndex<std::tuple_element_t<N, ifcopenshell::geometry::taxonomy::impl::CurvesTuple>, ifcopenshell::geometry::taxonomy::impl::KindsTuple>::value;
|
||||
static bool dispatch(const ifcopenshell::geom::taxonomy::ptr& item, T& visitor) {
|
||||
constexpr auto KindIndex = tuple_type_index<std::tuple_element_t<N, ifcopenshell::geom::taxonomy::impl::curves_tuple>, ifcopenshell::geom::taxonomy::impl::kinds_tuple>::value;
|
||||
if (item->kind() == KindIndex) {
|
||||
auto concrete_item = std::static_pointer_cast<ifcopenshell::geometry::taxonomy::curves::type<N>>(item);
|
||||
auto concrete_item = std::static_pointer_cast<ifcopenshell::geom::taxonomy::curves::type<N>>(item);
|
||||
visitor(concrete_item);
|
||||
return true;
|
||||
} else {
|
||||
@@ -227,8 +227,8 @@ namespace {
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct dispatch_curve_creation<T, ifcopenshell::geometry::taxonomy::curves::max> {
|
||||
static bool dispatch(const ifcopenshell::geometry::taxonomy::ptr& item, T&) {
|
||||
struct dispatch_curve_creation<T, ifcopenshell::geom::taxonomy::curves::max> {
|
||||
static bool dispatch(const ifcopenshell::geom::taxonomy::ptr& item, T&) {
|
||||
::logger::root().error("GEO", 28, "No conversion for " + std::to_string(item->kind()));
|
||||
return false;
|
||||
}
|
||||
@@ -237,8 +237,8 @@ namespace {
|
||||
/* A compile-time for loop over the curve kinds */
|
||||
template <typename T, size_t N = 0>
|
||||
struct dispatch_surface_creation {
|
||||
static bool dispatch(const ifcopenshell::geometry::taxonomy::ptr& item, T& visitor) {
|
||||
auto v = ifcopenshell::geometry::taxonomy::template dcast<ifcopenshell::geometry::taxonomy::surfaces::type<N>>(item);
|
||||
static bool dispatch(const ifcopenshell::geom::taxonomy::ptr& item, T& visitor) {
|
||||
auto v = ifcopenshell::geom::taxonomy::template dcast<ifcopenshell::geom::taxonomy::surfaces::type<N>>(item);
|
||||
if (v && item->kind() == v->kind()) {
|
||||
visitor(v);
|
||||
return true;
|
||||
@@ -249,8 +249,8 @@ namespace {
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct dispatch_surface_creation<T, ifcopenshell::geometry::taxonomy::surfaces::max> {
|
||||
static bool dispatch(const ifcopenshell::geometry::taxonomy::ptr& item, T&) {
|
||||
struct dispatch_surface_creation<T, ifcopenshell::geom::taxonomy::surfaces::max> {
|
||||
static bool dispatch(const ifcopenshell::geom::taxonomy::ptr& item, T&) {
|
||||
::logger::root().error("GEO", 29, "No conversion for " + std::to_string(item->kind()));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
#include "ConversionResult.h"
|
||||
#include "IfcGeomRepresentation.h"
|
||||
|
||||
IfcGeom::Representation::Triangulation* IfcGeom::ConversionResultShape::Triangulate(const ifcopenshell::geometry::Settings& settings, ::logger& logger) const
|
||||
ifcopenshell::geom::Representation::triangulation* ifcopenshell::geom::conversion_result_shape::Triangulate(const ifcopenshell::geom::settings& settings, ::logger& logger) const
|
||||
{
|
||||
auto t = IfcGeom::Representation::Triangulation::empty(settings);
|
||||
static ifcopenshell::geometry::taxonomy::matrix4 iden;
|
||||
auto t = ifcopenshell::geom::Representation::triangulation::empty(settings);
|
||||
static ifcopenshell::geom::taxonomy::matrix4 iden;
|
||||
Triangulate(settings, iden, t, -1, -1, logger);
|
||||
return t;
|
||||
}
|
||||
|
||||
using namespace ifcopenshell::geometry::taxonomy;
|
||||
using namespace ifcopenshell::geom::taxonomy;
|
||||
|
||||
void IfcGeom::ConversionResult::append(ifcopenshell::geometry::taxonomy::matrix4::ptr trsf) {
|
||||
void ifcopenshell::geom::conversion_result::append(ifcopenshell::geom::taxonomy::matrix4::ptr trsf) {
|
||||
placement_ = make<matrix4>(placement_->ccomponents() * trsf->ccomponents());
|
||||
}
|
||||
|
||||
void IfcGeom::ConversionResult::prepend(ifcopenshell::geometry::taxonomy::matrix4::ptr trsf) {
|
||||
void ifcopenshell::geom::conversion_result::prepend(ifcopenshell::geom::taxonomy::matrix4::ptr trsf) {
|
||||
placement_ = make<matrix4>(trsf->ccomponents() * placement_->ccomponents());
|
||||
}
|
||||
|
||||
template struct IFC_GEOM_API IfcGeom::OpaqueCoordinate<3>;
|
||||
template struct IFC_GEOM_API IfcGeom::OpaqueCoordinate<4>;
|
||||
template struct IFC_GEOM_API ifcopenshell::geom::opaque_coordinate<3>;
|
||||
template struct IFC_GEOM_API ifcopenshell::geom::opaque_coordinate<4>;
|
||||
|
||||
+156
-156
@@ -40,7 +40,7 @@
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
struct EdgeKey {
|
||||
struct edge_key {
|
||||
int v1, v2;
|
||||
|
||||
// These are not part of the hash or equality,
|
||||
@@ -51,7 +51,7 @@ struct EdgeKey {
|
||||
// conflicting original vertex indices.
|
||||
int ov1, ov2;
|
||||
|
||||
EdgeKey(int a, int b)
|
||||
edge_key(int a, int b)
|
||||
: ov1(a)
|
||||
, ov2(b)
|
||||
{
|
||||
@@ -64,7 +64,7 @@ struct EdgeKey {
|
||||
}
|
||||
}
|
||||
|
||||
bool operator==(const EdgeKey& other) const {
|
||||
bool operator==(const edge_key& other) const {
|
||||
return v1 == other.v1 && v2 == other.v2;
|
||||
}
|
||||
};
|
||||
@@ -72,18 +72,18 @@ struct EdgeKey {
|
||||
#ifndef SWIG
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<EdgeKey> {
|
||||
std::size_t operator()(const EdgeKey& ek) const {
|
||||
struct hash<edge_key> {
|
||||
std::size_t operator()(const edge_key& ek) const {
|
||||
return std::hash<int>()(ek.v1) ^ std::hash<int>()(ek.v2);
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace IfcGeom {
|
||||
namespace ifcopenshell::geom {
|
||||
|
||||
namespace Representation {
|
||||
class IFC_GEOM_API Triangulation;
|
||||
class IFC_GEOM_API triangulation;
|
||||
}
|
||||
|
||||
#ifndef SWIG
|
||||
@@ -123,21 +123,21 @@ namespace IfcGeom {
|
||||
}
|
||||
#endif
|
||||
|
||||
class IFC_GEOM_API OpaqueNumber {
|
||||
class IFC_GEOM_API opaque_number {
|
||||
protected:
|
||||
struct NumberConcept {
|
||||
virtual ~NumberConcept() {}
|
||||
struct number_concept {
|
||||
virtual ~number_concept() {}
|
||||
virtual double to_double() const = 0;
|
||||
virtual std::string to_string() const = 0;
|
||||
virtual std::shared_ptr<const NumberConcept> add(const NumberConcept& other) const = 0;
|
||||
virtual std::shared_ptr<const NumberConcept> subtract(const NumberConcept& other) const = 0;
|
||||
virtual std::shared_ptr<const NumberConcept> multiply(const NumberConcept& other) const = 0;
|
||||
virtual std::shared_ptr<const NumberConcept> divide(const NumberConcept& other) const = 0;
|
||||
virtual std::shared_ptr<const NumberConcept> negate() const = 0;
|
||||
virtual std::shared_ptr<const NumberConcept> from_double(double value) const = 0;
|
||||
virtual std::shared_ptr<const NumberConcept> from_int(int value) const = 0;
|
||||
virtual bool equals(const NumberConcept& other) const = 0;
|
||||
virtual bool less_than(const NumberConcept& other) const = 0;
|
||||
virtual std::shared_ptr<const number_concept> add(const number_concept& other) const = 0;
|
||||
virtual std::shared_ptr<const number_concept> subtract(const number_concept& other) const = 0;
|
||||
virtual std::shared_ptr<const number_concept> multiply(const number_concept& other) const = 0;
|
||||
virtual std::shared_ptr<const number_concept> divide(const number_concept& other) const = 0;
|
||||
virtual std::shared_ptr<const number_concept> negate() const = 0;
|
||||
virtual std::shared_ptr<const number_concept> from_double(double value) const = 0;
|
||||
virtual std::shared_ptr<const number_concept> from_int(int value) const = 0;
|
||||
virtual bool equals(const number_concept& other) const = 0;
|
||||
virtual bool less_than(const number_concept& other) const = 0;
|
||||
virtual const std::type_info& type() const = 0;
|
||||
virtual const void* value_ptr() const = 0;
|
||||
};
|
||||
@@ -151,14 +151,14 @@ namespace IfcGeom {
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
struct NumberModel : NumberConcept {
|
||||
struct number_model : number_concept {
|
||||
T value;
|
||||
|
||||
NumberModel(const T& v)
|
||||
number_model(const T& v)
|
||||
: value(v) {}
|
||||
|
||||
static const NumberModel& as_same(const NumberConcept& other) {
|
||||
auto same = dynamic_cast<const NumberModel*>(&other);
|
||||
static const number_model& as_same(const number_concept& other) {
|
||||
auto same = dynamic_cast<const number_model*>(&other);
|
||||
if (same == nullptr) {
|
||||
throw std::runtime_error("Incompatible opaque number types");
|
||||
}
|
||||
@@ -182,39 +182,39 @@ namespace IfcGeom {
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<const NumberConcept> add(const NumberConcept& other) const {
|
||||
return std::make_shared<NumberModel>(value + as_same(other).value);
|
||||
virtual std::shared_ptr<const number_concept> add(const number_concept& other) const {
|
||||
return std::make_shared<number_model>(value + as_same(other).value);
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<const NumberConcept> subtract(const NumberConcept& other) const {
|
||||
return std::make_shared<NumberModel>(value - as_same(other).value);
|
||||
virtual std::shared_ptr<const number_concept> subtract(const number_concept& other) const {
|
||||
return std::make_shared<number_model>(value - as_same(other).value);
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<const NumberConcept> multiply(const NumberConcept& other) const {
|
||||
return std::make_shared<NumberModel>(value * as_same(other).value);
|
||||
virtual std::shared_ptr<const number_concept> multiply(const number_concept& other) const {
|
||||
return std::make_shared<number_model>(value * as_same(other).value);
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<const NumberConcept> divide(const NumberConcept& other) const {
|
||||
return std::make_shared<NumberModel>(value / as_same(other).value);
|
||||
virtual std::shared_ptr<const number_concept> divide(const number_concept& other) const {
|
||||
return std::make_shared<number_model>(value / as_same(other).value);
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<const NumberConcept> negate() const {
|
||||
return std::make_shared<NumberModel>(-value);
|
||||
virtual std::shared_ptr<const number_concept> negate() const {
|
||||
return std::make_shared<number_model>(-value);
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<const NumberConcept> from_double(double v) const {
|
||||
return std::make_shared<NumberModel>(T(v));
|
||||
virtual std::shared_ptr<const number_concept> from_double(double v) const {
|
||||
return std::make_shared<number_model>(T(v));
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<const NumberConcept> from_int(int v) const {
|
||||
return std::make_shared<NumberModel>(T(v));
|
||||
virtual std::shared_ptr<const number_concept> from_int(int v) const {
|
||||
return std::make_shared<number_model>(T(v));
|
||||
}
|
||||
|
||||
virtual bool equals(const NumberConcept& other) const {
|
||||
virtual bool equals(const number_concept& other) const {
|
||||
return value == as_same(other).value;
|
||||
}
|
||||
|
||||
virtual bool less_than(const NumberConcept& other) const {
|
||||
virtual bool less_than(const number_concept& other) const {
|
||||
return value < as_same(other).value;
|
||||
}
|
||||
|
||||
@@ -234,9 +234,9 @@ namespace IfcGeom {
|
||||
struct is_shared_ptr<std::shared_ptr<T>> : std::true_type {};
|
||||
|
||||
private:
|
||||
std::shared_ptr<const NumberConcept> data_;
|
||||
std::shared_ptr<const number_concept> data_;
|
||||
|
||||
const NumberConcept& data() const {
|
||||
const number_concept& data() const {
|
||||
if (!data_) {
|
||||
throw std::runtime_error("Empty opaque number");
|
||||
}
|
||||
@@ -244,20 +244,20 @@ namespace IfcGeom {
|
||||
}
|
||||
|
||||
protected:
|
||||
OpaqueNumber(std::shared_ptr<const NumberConcept> data)
|
||||
opaque_number(std::shared_ptr<const number_concept> data)
|
||||
: data_(std::move(data)) {}
|
||||
|
||||
public:
|
||||
OpaqueNumber() = default;
|
||||
virtual ~OpaqueNumber() = default;
|
||||
opaque_number() = default;
|
||||
virtual ~opaque_number() = default;
|
||||
|
||||
#ifndef SWIG
|
||||
template <
|
||||
typename T,
|
||||
typename Decayed = std::decay_t<T>,
|
||||
typename = std::enable_if_t<!std::is_base_of<OpaqueNumber, Decayed>::value && !is_shared_ptr<Decayed>::value>>
|
||||
explicit OpaqueNumber(T&& value)
|
||||
: data_(std::make_shared<NumberModel<Decayed>>(std::forward<T>(value))) {}
|
||||
typename = std::enable_if_t<!std::is_base_of<opaque_number, Decayed>::value && !is_shared_ptr<Decayed>::value>>
|
||||
explicit opaque_number(T&& value)
|
||||
: data_(std::make_shared<number_model<Decayed>>(std::forward<T>(value))) {}
|
||||
#endif
|
||||
|
||||
double to_double() const {
|
||||
@@ -280,102 +280,102 @@ namespace IfcGeom {
|
||||
return *static_cast<const T*>(data().value_ptr());
|
||||
}
|
||||
|
||||
OpaqueNumber add(const OpaqueNumber& other) const {
|
||||
return OpaqueNumber(data().add(other.data()));
|
||||
opaque_number add(const opaque_number& other) const {
|
||||
return opaque_number(data().add(other.data()));
|
||||
}
|
||||
|
||||
OpaqueNumber subtract(const OpaqueNumber& other) const {
|
||||
return OpaqueNumber(data().subtract(other.data()));
|
||||
opaque_number subtract(const opaque_number& other) const {
|
||||
return opaque_number(data().subtract(other.data()));
|
||||
}
|
||||
|
||||
OpaqueNumber multiply(const OpaqueNumber& other) const {
|
||||
return OpaqueNumber(data().multiply(other.data()));
|
||||
opaque_number multiply(const opaque_number& other) const {
|
||||
return opaque_number(data().multiply(other.data()));
|
||||
}
|
||||
|
||||
OpaqueNumber divide(const OpaqueNumber& other) const {
|
||||
return OpaqueNumber(data().divide(other.data()));
|
||||
opaque_number divide(const opaque_number& other) const {
|
||||
return opaque_number(data().divide(other.data()));
|
||||
}
|
||||
|
||||
OpaqueNumber negated() const {
|
||||
return OpaqueNumber(data().negate());
|
||||
opaque_number negated() const {
|
||||
return opaque_number(data().negate());
|
||||
}
|
||||
|
||||
OpaqueNumber abs() const {
|
||||
opaque_number abs() const {
|
||||
auto zero = data().from_int(0);
|
||||
return OpaqueNumber(data().less_than(*zero) ? data().negate() : *this);
|
||||
return opaque_number(data().less_than(*zero) ? data().negate() : *this);
|
||||
}
|
||||
|
||||
OpaqueNumber same_type(double value) const {
|
||||
return OpaqueNumber(data().from_double(value));
|
||||
opaque_number same_type(double value) const {
|
||||
return opaque_number(data().from_double(value));
|
||||
}
|
||||
|
||||
OpaqueNumber same_type(int value) const {
|
||||
return OpaqueNumber(data().from_int(value));
|
||||
opaque_number same_type(int value) const {
|
||||
return opaque_number(data().from_int(value));
|
||||
}
|
||||
|
||||
bool equals(const OpaqueNumber& other) const {
|
||||
bool equals(const opaque_number& other) const {
|
||||
return data().equals(other.data());
|
||||
}
|
||||
|
||||
bool less_than(const OpaqueNumber& other) const {
|
||||
bool less_than(const opaque_number& other) const {
|
||||
return data().less_than(other.data());
|
||||
}
|
||||
|
||||
OpaqueNumber operator+(const OpaqueNumber& other) const {
|
||||
opaque_number operator+(const opaque_number& other) const {
|
||||
return add(other);
|
||||
}
|
||||
|
||||
OpaqueNumber operator-(const OpaqueNumber& other) const {
|
||||
opaque_number operator-(const opaque_number& other) const {
|
||||
return subtract(other);
|
||||
}
|
||||
|
||||
OpaqueNumber operator*(const OpaqueNumber& other) const {
|
||||
opaque_number operator*(const opaque_number& other) const {
|
||||
return multiply(other);
|
||||
}
|
||||
|
||||
OpaqueNumber operator/(const OpaqueNumber& other) const {
|
||||
opaque_number operator/(const opaque_number& other) const {
|
||||
return divide(other);
|
||||
}
|
||||
|
||||
bool operator==(const OpaqueNumber& other) const {
|
||||
bool operator==(const opaque_number& other) const {
|
||||
return equals(other);
|
||||
}
|
||||
|
||||
bool operator<(const OpaqueNumber& other) const {
|
||||
bool operator<(const opaque_number& other) const {
|
||||
return less_than(other);
|
||||
}
|
||||
|
||||
OpaqueNumber operator-() const {
|
||||
opaque_number operator-() const {
|
||||
return negated();
|
||||
}
|
||||
};
|
||||
#ifndef SWIG
|
||||
template <size_t N>
|
||||
struct IFC_GEOM_API OpaqueCoordinate {
|
||||
struct IFC_GEOM_API opaque_coordinate {
|
||||
private:
|
||||
std::array<OpaqueNumber, N> values_;
|
||||
std::array<opaque_number, N> values_;
|
||||
|
||||
static OpaqueNumber as_number(OpaqueNumber value) {
|
||||
static opaque_number as_number(opaque_number value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
public:
|
||||
#ifndef SWIG
|
||||
template <typename... Args, typename = std::enable_if_t<sizeof...(Args) == N>>
|
||||
OpaqueCoordinate(Args&&... args) {
|
||||
opaque_coordinate(Args&&... args) {
|
||||
init_<0>(std::forward<Args>(args)...);
|
||||
}
|
||||
#endif
|
||||
|
||||
OpaqueCoordinate() = default;
|
||||
opaque_coordinate() = default;
|
||||
|
||||
std::size_t size() const {
|
||||
return N;
|
||||
}
|
||||
|
||||
OpaqueNumber get(size_t i) const {
|
||||
opaque_number get(size_t i) const {
|
||||
if (i >= N) {
|
||||
return OpaqueNumber();
|
||||
return opaque_number();
|
||||
}
|
||||
return values_[i];
|
||||
}
|
||||
@@ -384,7 +384,7 @@ namespace IfcGeom {
|
||||
return get(i).to_double();
|
||||
}
|
||||
|
||||
void set(size_t i, const OpaqueNumber& n) {
|
||||
void set(size_t i, const opaque_number& n) {
|
||||
if (i < N) {
|
||||
values_[i] = n;
|
||||
}
|
||||
@@ -399,55 +399,55 @@ namespace IfcGeom {
|
||||
return result;
|
||||
}
|
||||
|
||||
OpaqueCoordinate operator-() const {
|
||||
OpaqueCoordinate result;
|
||||
opaque_coordinate operator-() const {
|
||||
opaque_coordinate result;
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
result.values_[i] = values_[i].negated();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
OpaqueCoordinate operator+(const OpaqueCoordinate& other) const {
|
||||
OpaqueCoordinate result;
|
||||
opaque_coordinate operator+(const opaque_coordinate& other) const {
|
||||
opaque_coordinate result;
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
result.values_[i] = values_[i].add(other.values_[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
OpaqueCoordinate operator-(const OpaqueCoordinate& other) const {
|
||||
OpaqueCoordinate result;
|
||||
opaque_coordinate operator-(const opaque_coordinate& other) const {
|
||||
opaque_coordinate result;
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
result.values_[i] = values_[i].subtract(other.values_[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
OpaqueCoordinate operator*(const OpaqueNumber& scalar) const {
|
||||
OpaqueCoordinate result;
|
||||
opaque_coordinate operator*(const opaque_number& scalar) const {
|
||||
opaque_coordinate result;
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
result.values_[i] = values_[i].multiply(scalar);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
OpaqueCoordinate operator/(const OpaqueNumber& scalar) const {
|
||||
OpaqueCoordinate result;
|
||||
opaque_coordinate operator/(const opaque_number& scalar) const {
|
||||
opaque_coordinate result;
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
result.values_[i] = values_[i].divide(scalar);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
OpaqueCoordinate scale(double scalar) const {
|
||||
opaque_coordinate scale(double scalar) const {
|
||||
return *this * values_[0].same_type(scalar);
|
||||
}
|
||||
|
||||
OpaqueNumber dot(const OpaqueCoordinate& other) const {
|
||||
opaque_number dot(const opaque_coordinate& other) const {
|
||||
if constexpr (N == 0) {
|
||||
return OpaqueNumber(0.0);
|
||||
return opaque_number(0.0);
|
||||
} else {
|
||||
OpaqueNumber result = values_[0].multiply(other.values_[0]);
|
||||
opaque_number result = values_[0].multiply(other.values_[0]);
|
||||
for (size_t i = 1; i < N; ++i) {
|
||||
result = result.add(values_[i].multiply(other.values_[i]));
|
||||
}
|
||||
@@ -459,7 +459,7 @@ namespace IfcGeom {
|
||||
return std::sqrt(dot(*this).to_double());
|
||||
}
|
||||
|
||||
OpaqueCoordinate normalized() const {
|
||||
opaque_coordinate normalized() const {
|
||||
const double length = norm();
|
||||
if (length == 0.0) {
|
||||
return *this;
|
||||
@@ -467,7 +467,7 @@ namespace IfcGeom {
|
||||
return *this / values_[0].same_type(length);
|
||||
}
|
||||
|
||||
OpaqueCoordinate normalized_by_max_abs() const {
|
||||
opaque_coordinate normalized_by_max_abs() const {
|
||||
double max_abs = 0.0;
|
||||
for (const auto& value : values_) {
|
||||
max_abs = (std::max)(max_abs, std::fabs(value.to_double()));
|
||||
@@ -489,29 +489,29 @@ namespace IfcGeom {
|
||||
};
|
||||
#else
|
||||
template <size_t N>
|
||||
struct IFC_GEOM_API OpaqueCoordinate {
|
||||
OpaqueCoordinate();
|
||||
OpaqueCoordinate(const OpaqueCoordinate& other);
|
||||
OpaqueCoordinate& operator=(const OpaqueCoordinate& other);
|
||||
~OpaqueCoordinate();
|
||||
struct IFC_GEOM_API opaque_coordinate {
|
||||
opaque_coordinate();
|
||||
opaque_coordinate(const opaque_coordinate& other);
|
||||
opaque_coordinate& operator=(const opaque_coordinate& other);
|
||||
~opaque_coordinate();
|
||||
std::size_t size() const;
|
||||
OpaqueNumber get(size_t i) const;
|
||||
opaque_number get(size_t i) const;
|
||||
double get_double(size_t i) const;
|
||||
void set(size_t i, const OpaqueNumber& n);
|
||||
void set(size_t i, const opaque_number& n);
|
||||
std::vector<double> to_double() const;
|
||||
};
|
||||
#endif
|
||||
|
||||
class IFC_GEOM_API ConversionResultShape {
|
||||
class IFC_GEOM_API conversion_result_shape {
|
||||
public:
|
||||
#ifdef SWIG
|
||||
virtual std::string backend_id() const = 0;
|
||||
#else
|
||||
virtual std::string_view backend_id() const = 0;
|
||||
#endif
|
||||
virtual void Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, Representation::Triangulation* t, int item_id, int surface_style_id, ::logger& logger = ::logger::root()) const = 0;
|
||||
IfcGeom::Representation::Triangulation* Triangulate(const ifcopenshell::geometry::Settings& settings, ::logger& logger = ::logger::root()) const;
|
||||
virtual void Serialize(const ifcopenshell::geometry::taxonomy::matrix4& place, std::string&) const = 0;
|
||||
virtual void Triangulate(ifcopenshell::geom::settings settings, const ifcopenshell::geom::taxonomy::matrix4& place, Representation::triangulation* t, int item_id, int surface_style_id, ::logger& logger = ::logger::root()) const = 0;
|
||||
ifcopenshell::geom::Representation::triangulation* Triangulate(const ifcopenshell::geom::settings& settings, ::logger& logger = ::logger::root()) const;
|
||||
virtual void Serialize(const ifcopenshell::geom::taxonomy::matrix4& place, std::string&) const = 0;
|
||||
|
||||
virtual int surface_genus() const = 0;
|
||||
virtual bool is_manifold() const = 0;
|
||||
@@ -523,73 +523,73 @@ namespace IfcGeom {
|
||||
// @todo choose one prototype
|
||||
virtual double bounding_box(void*&) const = 0;
|
||||
// @todo this must be something with a virtual dtor so that we can delete it.
|
||||
virtual std::pair<OpaqueCoordinate<3>, OpaqueCoordinate<3>> bounding_box() const = 0;
|
||||
virtual std::pair<opaque_coordinate<3>, opaque_coordinate<3>> bounding_box() const = 0;
|
||||
virtual void set_box(void* b) = 0;
|
||||
|
||||
virtual OpaqueNumber length() = 0;
|
||||
virtual OpaqueNumber area() = 0;
|
||||
virtual OpaqueNumber volume() = 0;
|
||||
virtual opaque_number length() = 0;
|
||||
virtual opaque_number area() = 0;
|
||||
virtual opaque_number volume() = 0;
|
||||
|
||||
virtual OpaqueCoordinate<3> position() = 0;
|
||||
virtual OpaqueCoordinate<3> axis() = 0;
|
||||
virtual OpaqueCoordinate<4> plane_equation() = 0;
|
||||
virtual opaque_coordinate<3> position() = 0;
|
||||
virtual opaque_coordinate<3> axis() = 0;
|
||||
virtual opaque_coordinate<4> plane_equation() = 0;
|
||||
|
||||
virtual std::vector<ConversionResultShape*> convex_decomposition() = 0;
|
||||
virtual ConversionResultShape* halfspaces() = 0;
|
||||
virtual ConversionResultShape* box() = 0;
|
||||
virtual ConversionResultShape* solid() = 0;
|
||||
virtual ConversionResultShape* wrap_in_compound() = 0;
|
||||
virtual std::vector<conversion_result_shape*> convex_decomposition() = 0;
|
||||
virtual conversion_result_shape* halfspaces() = 0;
|
||||
virtual conversion_result_shape* box() = 0;
|
||||
virtual conversion_result_shape* solid() = 0;
|
||||
virtual conversion_result_shape* wrap_in_compound() = 0;
|
||||
|
||||
virtual std::vector<ConversionResultShape*> vertices() = 0;
|
||||
virtual std::vector<ConversionResultShape*> edges() = 0;
|
||||
virtual std::vector<ConversionResultShape*> facets() = 0;
|
||||
virtual std::vector<conversion_result_shape*> vertices() = 0;
|
||||
virtual std::vector<conversion_result_shape*> edges() = 0;
|
||||
virtual std::vector<conversion_result_shape*> facets() = 0;
|
||||
|
||||
virtual ConversionResultShape* add(ConversionResultShape*) = 0;
|
||||
virtual ConversionResultShape* subtract(ConversionResultShape*) = 0;
|
||||
virtual ConversionResultShape* intersect(ConversionResultShape*) = 0;
|
||||
virtual ConversionResultShape* concat(ConversionResultShape*) = 0;
|
||||
virtual conversion_result_shape* add(conversion_result_shape*) = 0;
|
||||
virtual conversion_result_shape* subtract(conversion_result_shape*) = 0;
|
||||
virtual conversion_result_shape* intersect(conversion_result_shape*) = 0;
|
||||
virtual conversion_result_shape* concat(conversion_result_shape*) = 0;
|
||||
|
||||
virtual std::size_t map(OpaqueCoordinate<4>& from, OpaqueCoordinate<4>& to) = 0;
|
||||
virtual std::size_t map(const std::vector<OpaqueCoordinate<4>>& from, const std::vector<OpaqueCoordinate<4>>& to) = 0;
|
||||
virtual ConversionResultShape* moved(ifcopenshell::geometry::taxonomy::matrix4::ptr) const = 0;
|
||||
virtual std::size_t map(opaque_coordinate<4>& from, opaque_coordinate<4>& to) = 0;
|
||||
virtual std::size_t map(const std::vector<opaque_coordinate<4>>& from, const std::vector<opaque_coordinate<4>>& to) = 0;
|
||||
virtual conversion_result_shape* moved(ifcopenshell::geom::taxonomy::matrix4::ptr) const = 0;
|
||||
|
||||
virtual bool surface_area_along_direction(double tol, const ifcopenshell::geometry::taxonomy::matrix4::ptr&, double& along_x, double& along_y, double& along_z) const = 0;
|
||||
virtual bool surface_area_along_direction(double tol, const ifcopenshell::geom::taxonomy::matrix4::ptr&, double& along_x, double& along_y, double& along_z) const = 0;
|
||||
|
||||
virtual ~ConversionResultShape() {}
|
||||
virtual ~conversion_result_shape() {}
|
||||
|
||||
};
|
||||
|
||||
class IFC_GEOM_API ConversionResult {
|
||||
class IFC_GEOM_API conversion_result {
|
||||
private:
|
||||
int id;
|
||||
ifcopenshell::geometry::taxonomy::matrix4::ptr placement_;
|
||||
std::shared_ptr<ConversionResultShape> shape_;
|
||||
ifcopenshell::geometry::taxonomy::style::ptr style_;
|
||||
ifcopenshell::geom::taxonomy::matrix4::ptr placement_;
|
||||
std::shared_ptr<conversion_result_shape> shape_;
|
||||
ifcopenshell::geom::taxonomy::style::ptr style_;
|
||||
public:
|
||||
ConversionResult(int id, ifcopenshell::geometry::taxonomy::matrix4::ptr placement, ConversionResultShape* shape, ifcopenshell::geometry::taxonomy::style::ptr style)
|
||||
: id(id), placement_(placement ? placement : ifcopenshell::geometry::taxonomy::make<ifcopenshell::geometry::taxonomy::matrix4>()), shape_(shape), style_(style)
|
||||
conversion_result(int id, ifcopenshell::geom::taxonomy::matrix4::ptr placement, conversion_result_shape* shape, ifcopenshell::geom::taxonomy::style::ptr style)
|
||||
: id(id), placement_(placement ? placement : ifcopenshell::geom::taxonomy::make<ifcopenshell::geom::taxonomy::matrix4>()), shape_(shape), style_(style)
|
||||
{}
|
||||
ConversionResult(int id, ifcopenshell::geometry::taxonomy::matrix4::ptr placement, ConversionResultShape* shape)
|
||||
: id(id), placement_(placement ? placement : ifcopenshell::geometry::taxonomy::make<ifcopenshell::geometry::taxonomy::matrix4>()), shape_(shape)
|
||||
conversion_result(int id, ifcopenshell::geom::taxonomy::matrix4::ptr placement, conversion_result_shape* shape)
|
||||
: id(id), placement_(placement ? placement : ifcopenshell::geom::taxonomy::make<ifcopenshell::geom::taxonomy::matrix4>()), shape_(shape)
|
||||
{}
|
||||
ConversionResult(int id, ConversionResultShape* shape, ifcopenshell::geometry::taxonomy::style::ptr style)
|
||||
: id(id), placement_(ifcopenshell::geometry::taxonomy::make<ifcopenshell::geometry::taxonomy::matrix4>()), shape_(shape), style_(style)
|
||||
conversion_result(int id, conversion_result_shape* shape, ifcopenshell::geom::taxonomy::style::ptr style)
|
||||
: id(id), placement_(ifcopenshell::geom::taxonomy::make<ifcopenshell::geom::taxonomy::matrix4>()), shape_(shape), style_(style)
|
||||
{}
|
||||
ConversionResult(int id, ConversionResultShape* shape)
|
||||
: id(id), placement_(ifcopenshell::geometry::taxonomy::make<ifcopenshell::geometry::taxonomy::matrix4>()), shape_(shape)
|
||||
conversion_result(int id, conversion_result_shape* shape)
|
||||
: id(id), placement_(ifcopenshell::geom::taxonomy::make<ifcopenshell::geom::taxonomy::matrix4>()), shape_(shape)
|
||||
{}
|
||||
void append(ifcopenshell::geometry::taxonomy::matrix4::ptr trsf);
|
||||
void prepend(ifcopenshell::geometry::taxonomy::matrix4::ptr trsf);
|
||||
std::shared_ptr<ConversionResultShape> Shape() const { return shape_; }
|
||||
ifcopenshell::geometry::taxonomy::matrix4::ptr Placement() const { return placement_; }
|
||||
void append(ifcopenshell::geom::taxonomy::matrix4::ptr trsf);
|
||||
void prepend(ifcopenshell::geom::taxonomy::matrix4::ptr trsf);
|
||||
std::shared_ptr<conversion_result_shape> Shape() const { return shape_; }
|
||||
ifcopenshell::geom::taxonomy::matrix4::ptr Placement() const { return placement_; }
|
||||
bool hasStyle() const { return !!style_; }
|
||||
const ifcopenshell::geometry::taxonomy::style& Style() const { return *style_; }
|
||||
ifcopenshell::geometry::taxonomy::style::ptr StylePtr() const { return style_; }
|
||||
void setStyle(ifcopenshell::geometry::taxonomy::style::ptr newStyle) { style_ = newStyle; }
|
||||
const ifcopenshell::geom::taxonomy::style& Style() const { return *style_; }
|
||||
ifcopenshell::geom::taxonomy::style::ptr StylePtr() const { return style_; }
|
||||
void setStyle(ifcopenshell::geom::taxonomy::style::ptr newStyle) { style_ = newStyle; }
|
||||
int ItemId() const { return id; }
|
||||
ConversionResultShape* apply_transform(double unit_scale = 1.) const {
|
||||
conversion_result_shape* apply_transform(double unit_scale = 1.) const {
|
||||
if (unit_scale != 1.) {
|
||||
auto m = ifcopenshell::geometry::taxonomy::matrix4::ptr(placement_->clone_());
|
||||
auto m = ifcopenshell::geom::taxonomy::matrix4::ptr(placement_->clone_());
|
||||
m->pre_multiply_scale(unit_scale);
|
||||
return shape_->moved(m);
|
||||
} else {
|
||||
@@ -598,17 +598,17 @@ namespace IfcGeom {
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<ConversionResult> ConversionResults;
|
||||
typedef std::vector<conversion_result> conversion_results;
|
||||
|
||||
#ifndef SWIG
|
||||
namespace util {
|
||||
// @todo this is now moved to occt kernel, do we need something similar in cgal?
|
||||
// bool flatten_shape_list(const IfcGeom::ConversionResults& shapes, TopoDS_Shape& result, bool fuse, double tol);
|
||||
// bool flatten_shape_list(const ifcopenshell::geom::conversion_results& shapes, TopoDS_Shape& result, bool fuse, double tol);
|
||||
|
||||
// Function to find boundary loops from triangles
|
||||
template <typename NT>
|
||||
std::vector<std::vector<int>> find_boundary_loops(const std::vector<NT>& positions, const std::vector<std::tuple<int, int, int>>& triangles) {
|
||||
std::unordered_map<EdgeKey, int> edge_count;
|
||||
std::unordered_map<edge_key, int> edge_count;
|
||||
|
||||
// Count how many triangles each edge belongs to
|
||||
for (const auto& triangle : triangles) {
|
||||
@@ -621,7 +621,7 @@ namespace IfcGeom {
|
||||
}
|
||||
|
||||
// Boundary edges have count 1
|
||||
std::vector<EdgeKey> boundary_edges;
|
||||
std::vector<edge_key> boundary_edges;
|
||||
for (auto& p : edge_count) {
|
||||
if (p.second == 1) {
|
||||
boundary_edges.push_back(p.first);
|
||||
|
||||
@@ -32,7 +32,7 @@ std::istream& std::operator>>(istream& in, vector<double>& ds) {
|
||||
return in;
|
||||
}
|
||||
|
||||
std::istream& ifcopenshell::geometry::settings::operator>>(std::istream& in, IteratorOutputOptions& ioo)
|
||||
std::istream& ifcopenshell::geom::settings_detail::operator>>(std::istream& in, IteratorOutputOptions& ioo)
|
||||
{
|
||||
std::string token;
|
||||
in >> token;
|
||||
@@ -49,7 +49,7 @@ std::istream& ifcopenshell::geometry::settings::operator>>(std::istream& in, Ite
|
||||
return in;
|
||||
}
|
||||
|
||||
std::istream& ifcopenshell::geometry::settings::operator>>(std::istream& in, FunctionStepMethod& ioo) {
|
||||
std::istream& ifcopenshell::geom::settings_detail::operator>>(std::istream& in, FunctionStepMethod& ioo) {
|
||||
std::string token;
|
||||
in >> token;
|
||||
boost::to_upper(token);
|
||||
@@ -63,7 +63,7 @@ std::istream& ifcopenshell::geometry::settings::operator>>(std::istream& in, Fun
|
||||
return in;
|
||||
}
|
||||
|
||||
std::istream& ifcopenshell::geometry::settings::operator>>(std::istream& in, OutputDimensionalityTypes& v) {
|
||||
std::istream& ifcopenshell::geom::settings_detail::operator>>(std::istream& in, OutputDimensionalityTypes& v) {
|
||||
std::string token;
|
||||
in >> token;
|
||||
boost::to_upper(token);
|
||||
@@ -79,7 +79,7 @@ std::istream& ifcopenshell::geometry::settings::operator>>(std::istream& in, Out
|
||||
return in;
|
||||
}
|
||||
|
||||
std::istream& ifcopenshell::geometry::settings::operator>>(std::istream& in, TriangulationMethod& v) {
|
||||
std::istream& ifcopenshell::geom::settings_detail::operator>>(std::istream& in, TriangulationMethod& v) {
|
||||
std::string token;
|
||||
in >> token;
|
||||
boost::to_upper(token);
|
||||
@@ -95,6 +95,6 @@ std::istream& ifcopenshell::geometry::settings::operator>>(std::istream& in, Tri
|
||||
return in;
|
||||
}
|
||||
|
||||
IfcGeom::geometry_exception::~geometry_exception() = default;
|
||||
ifcopenshell::geom::geometry_exception::~geometry_exception() = default;
|
||||
|
||||
IfcGeom::too_many_faces_exception::~too_many_faces_exception() = default;
|
||||
ifcopenshell::geom::too_many_faces_exception::~too_many_faces_exception() = default;
|
||||
|
||||
@@ -29,8 +29,8 @@ namespace std {
|
||||
#endif
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace geometry {
|
||||
inline namespace settings {
|
||||
namespace geom {
|
||||
namespace settings_detail {
|
||||
|
||||
#ifndef SWIG
|
||||
template <typename T, typename U = int>
|
||||
@@ -546,32 +546,32 @@ namespace ifcopenshell {
|
||||
};
|
||||
|
||||
template <>
|
||||
struct readable_name<IteratorOutputOptions> {
|
||||
struct readable_name<settings_detail::IteratorOutputOptions> {
|
||||
static constexpr const char* name = "IteratorOutputOptions";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct readable_name<FunctionStepMethod> {
|
||||
struct readable_name<settings_detail::FunctionStepMethod> {
|
||||
static constexpr const char* name = "FunctionStepMethod";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct readable_name<OutputDimensionalityTypes> {
|
||||
struct readable_name<settings_detail::OutputDimensionalityTypes> {
|
||||
static constexpr const char* name = "OutputDimensionalityTypes";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct readable_name<TriangulationMethod> {
|
||||
struct readable_name<settings_detail::TriangulationMethod> {
|
||||
static constexpr const char* name = "TriangulationMethod";
|
||||
};
|
||||
}
|
||||
|
||||
template <typename settings_t>
|
||||
class SettingsContainer {
|
||||
class settings_container {
|
||||
public:
|
||||
typedef std::variant<bool, int, double, std::string, std::set<int>, std::set<std::string>,
|
||||
std::vector<double>, std::vector<std::string>, IteratorOutputOptions, FunctionStepMethod,
|
||||
OutputDimensionalityTypes, TriangulationMethod> value_variant_t;
|
||||
std::vector<double>, std::vector<std::string>, settings_detail::IteratorOutputOptions, settings_detail::FunctionStepMethod,
|
||||
settings_detail::OutputDimensionalityTypes, settings_detail::TriangulationMethod> value_variant_t;
|
||||
private:
|
||||
settings_t settings;
|
||||
|
||||
@@ -678,15 +678,461 @@ namespace ifcopenshell {
|
||||
}
|
||||
};
|
||||
|
||||
class Settings : public SettingsContainer<
|
||||
std::tuple<MesherLinearDeflection, MesherAngularDeflection, ReorientShells, LengthUnit, PlaneUnit, Precision, OutputDimensionality, LayersetFirst, DisableBooleanResult, NoWireIntersectionCheck, NoWireIntersectionTolerance, PrecisionFactor, DebugBooleanOperations, BooleanAttempt2d, SurfaceColour, WeldVertices, UseWorldCoords, UnifyShapes, UseMaterialNames, ConvertBackUnits, ContextIds, ContextTypes, ContextIdentifiers, ContextPriorities, IteratorOutput, DisableOpeningSubtractions, MaxVoidsPerElement, ApplyDefaultMaterials, DontEmitNormals, GenerateUvs, ApplyLayerSets, UseElementHierarchy, ValidateQuantities, EdgeArrows, BuildingLocalPlacement, SiteLocalPlacement, ForceSpaceTransparency, CircleSegments, CgalSmoothAngleDegrees, SvgRidgeAngleMinDegrees, SvgValleyAngleMinDegrees, SvgEmitFlushEdges, SvgUseEdgeClassification, SvgRenderCreaseEdges, SvgRenderSharpEdges, KeepBoundingBoxes, ComputeCurvature, FunctionStepType, FunctionStepParam, NoParallelMapping, PermissiveShapeReuse, ModelOffset, ModelRotation, TriangulationType, CgalEmitOriginalEdges, OcctNoCleanTriangulation, CacheShapes, DeferProcessingFirstElement, MaxOffset, MaxOffsetDeviation, ApplyOffset, MakeVolume>
|
||||
>
|
||||
{};
|
||||
namespace settings_detail {
|
||||
|
||||
struct UseElementNames : public settings_detail::SettingBase<UseElementNames, bool> {
|
||||
static constexpr const char* const name = "use-element-names";
|
||||
static constexpr const char* const description = "Use entity instance IfcRoot.Name instead of unique IDs for naming elements upon serialization. Applicable for OBJ, DAE, STP, and SVG output.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct UseElementGuids : public settings_detail::SettingBase<UseElementGuids, bool> {
|
||||
static constexpr const char* const name = "use-element-guids";
|
||||
static constexpr const char* const description = "Use entity instance IfcRoot.GlobalId instead of unique IDs for naming elements upon serialization. Applicable for OBJ, DAE, STP, and SVG output.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct UseElementStepIds : public settings_detail::SettingBase<UseElementStepIds, bool> {
|
||||
static constexpr const char* const name = "use-element-step-ids";
|
||||
static constexpr const char* const description = "Use the numeric step identifier (entity instance name) for naming elements upon serialization. Applicable for OBJ, DAE, STP, and SVG output.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct UseElementTypes : public settings_detail::SettingBase<UseElementTypes, bool> {
|
||||
static constexpr const char* const name = "use-element-types";
|
||||
static constexpr const char* const description = "Use element types instead of unique IDs for naming elements upon serialization. Applicable to DAE output.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct UseYUp : public settings_detail::SettingBase<UseYUp, bool> {
|
||||
static constexpr const char* const name = "y-up";
|
||||
static constexpr const char* const description = "Change the 'up' axis to positive Y, default is Z UP. Applicable to OBJ output.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct WriteGltfEcef : public settings_detail::SettingBase<WriteGltfEcef, bool> {
|
||||
static constexpr const char* const name = "ecef";
|
||||
static constexpr const char* const description = "Write glTF in Earth-Centered Earth-Fixed coordinates. Requires PROJ.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct FloatingPointDigits : public settings_detail::SettingBase<FloatingPointDigits, int> {
|
||||
static constexpr const char* const name = "digits";
|
||||
static constexpr const char* const description = "Sets the precision to be used to format floating-point values, 15 by default. Use a negative value to use the system's default precision (should be 6 typically). Applicable for OBJ and DAE output. For DAE output, value >= 15 means that up to 16 decimals are used, and any other value means that 6 or 7 decimals are used.";
|
||||
static constexpr int defaultvalue = 15;
|
||||
};
|
||||
|
||||
struct BaseUri : public settings_detail::SettingBase<BaseUri, std::string> {
|
||||
static constexpr const char* const name = "base-uri";
|
||||
static constexpr const char* const description = "Base URI for products to be used in RDF-based serializations.";
|
||||
};
|
||||
|
||||
struct WktUseSection : public settings_detail::SettingBase<WktUseSection, bool> {
|
||||
static constexpr const char* const name = "wkt-use-section";
|
||||
static constexpr const char* const description = "Use a geometrical section rather than full polyhedral output and footprint in TTL WKT";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SeparateZUpNode : public settings_detail::SettingBase<SeparateZUpNode, bool> {
|
||||
static constexpr const char* const name = "separate-z-up-node";
|
||||
static constexpr const char* const description = "Introduce a separate Z-Up node into the GlTF hierarchy instead of multiplying the transform into the root node matrices";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgBounds : public settings_detail::SettingBase<SvgBounds, std::string> {
|
||||
static constexpr const char* const name = "bounds";
|
||||
static constexpr const char* const description = "Specifies the bounding rectangle, for example 512x512, to which the output will be scaled. Only used when converting to SVG.";
|
||||
};
|
||||
|
||||
struct SvgScale : public settings_detail::SettingBase<SvgScale, std::string> {
|
||||
static constexpr const char* const name = "scale";
|
||||
static constexpr const char* const description = "Interprets SVG bounds in mm, centers layout and draw elements to scale. Only used when converting to SVG. Example 1:100.";
|
||||
};
|
||||
|
||||
struct SvgCenter : public settings_detail::SettingBase<SvgCenter, std::string> {
|
||||
static constexpr const char* const name = "center";
|
||||
static constexpr const char* const description = "When using --scale, specifies the location in the range [0 1]x[0 1] around which to center the drawings. Example 0.5x0.5.";
|
||||
};
|
||||
|
||||
struct SvgSectionRef : public settings_detail::SettingBase<SvgSectionRef, std::string> {
|
||||
static constexpr const char* const name = "section-ref";
|
||||
static constexpr const char* const description = "Element at which cross sections should be created.";
|
||||
};
|
||||
|
||||
struct SvgElevationRef : public settings_detail::SettingBase<SvgElevationRef, std::string> {
|
||||
static constexpr const char* const name = "elevation-ref";
|
||||
static constexpr const char* const description = "Element at which drawings should be created.";
|
||||
};
|
||||
|
||||
struct SvgElevationRefGuid : public settings_detail::SettingBase<SvgElevationRefGuid, std::string> {
|
||||
static constexpr const char* const name = "elevation-ref-guid";
|
||||
static constexpr const char* const description = "Element guids at which drawings should be created.";
|
||||
};
|
||||
|
||||
struct SvgAutoSection : public settings_detail::SettingBase<SvgAutoSection, bool> {
|
||||
static constexpr const char* const name = "auto-section";
|
||||
static constexpr const char* const description = "Creates SVG cross section drawings automatically based on model extents.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgAutoElevation : public settings_detail::SettingBase<SvgAutoElevation, bool> {
|
||||
static constexpr const char* const name = "auto-elevation";
|
||||
static constexpr const char* const description = "Creates SVG elevation drawings automatically based on model extents.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgDrawStoreyHeights : public settings_detail::SettingBase<SvgDrawStoreyHeights, std::string> {
|
||||
static constexpr const char* const name = "draw-storey-heights";
|
||||
static constexpr const char* const description = "Draws a horizontal line at the height of building storeys in vertical drawings. Accepted values are none, full, and left.";
|
||||
};
|
||||
|
||||
struct SvgProfileThreshold : public settings_detail::SettingBase<SvgProfileThreshold, int> {
|
||||
static constexpr const char* const name = "profile-threshold";
|
||||
static constexpr const char* const description = "Limits the number of projected wire profiles for non-wall and non-slab elements in SVG output. A negative value disables the limit.";
|
||||
static constexpr int defaultvalue = -1;
|
||||
};
|
||||
|
||||
struct SvgStoreyHeightLineLength : public settings_detail::SettingBase<SvgStoreyHeightLineLength, double> {
|
||||
static constexpr const char* const name = "storey-height-line-length";
|
||||
static constexpr const char* const description = "Length of the line when --draw-storey-heights=left.";
|
||||
};
|
||||
|
||||
struct SvgUseNamespace : public settings_detail::SettingBase<SvgUseNamespace, bool> {
|
||||
static constexpr const char* const name = "svg-xmlns";
|
||||
static constexpr const char* const description = "Stores name and guid in a separate namespace as opposed to data-name, data-guid.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgUseHlrPoly : public settings_detail::SettingBase<SvgUseHlrPoly, bool> {
|
||||
static constexpr const char* const name = "svg-poly";
|
||||
static constexpr const char* const description = "Uses the polygonal algorithm for hidden line rendering.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgUsePrefiltering : public settings_detail::SettingBase<SvgUsePrefiltering, bool> {
|
||||
static constexpr const char* const name = "svg-prefilter";
|
||||
static constexpr const char* const description = "Prefilter faces and shapes before feeding to the hidden-line algorithm.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgUnifyInputs : public settings_detail::SettingBase<SvgUnifyInputs, bool> {
|
||||
static constexpr const char* const name = "svg-unify-inputs";
|
||||
static constexpr const char* const description = "Unify input shapes before SVG projection.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgSegmentProjection : public settings_detail::SettingBase<SvgSegmentProjection, bool> {
|
||||
static constexpr const char* const name = "svg-segment-projection";
|
||||
static constexpr const char* const description = "Segment result of projection with respect to original products.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgSubtractBefore : public settings_detail::SettingBase<SvgSubtractBefore, std::string> {
|
||||
static constexpr const char* const name = "svg-subtract-before";
|
||||
static constexpr const char* const description = "Controls which shapes are cut before SVG hidden-line projection. Accepted values are auto, slabs-and-walls, and always.";
|
||||
};
|
||||
|
||||
struct SvgPolygonal : public settings_detail::SettingBase<SvgPolygonal, bool> {
|
||||
static constexpr const char* const name = "svg-write-poly";
|
||||
static constexpr const char* const description = "Approximate every curve as polygonal in SVG output.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgAlwaysProject : public settings_detail::SettingBase<SvgAlwaysProject, bool> {
|
||||
static constexpr const char* const name = "svg-project";
|
||||
static constexpr const char* const description = "Always enable hidden line rendering instead of only on elevations.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgWithoutStoreys : public settings_detail::SettingBase<SvgWithoutStoreys, bool> {
|
||||
static constexpr const char* const name = "svg-without-storeys";
|
||||
static constexpr const char* const description = "Do not emit drawings for building storeys.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgNoCss : public settings_detail::SettingBase<SvgNoCss, bool> {
|
||||
static constexpr const char* const name = "svg-no-css";
|
||||
static constexpr const char* const description = "Do not emit CSS style declarations.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgMirrorY : public settings_detail::SettingBase<SvgMirrorY, bool> {
|
||||
static constexpr const char* const name = "svg-mirror-y";
|
||||
static constexpr const char* const description = "Mirror SVG output along the Y axis.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgMirrorX : public settings_detail::SettingBase<SvgMirrorX, bool> {
|
||||
static constexpr const char* const name = "svg-mirror-x";
|
||||
static constexpr const char* const description = "Mirror SVG output along the X axis.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgDoorArcs : public settings_detail::SettingBase<SvgDoorArcs, bool> {
|
||||
static constexpr const char* const name = "door-arcs";
|
||||
static constexpr const char* const description = "Draw door opening arcs for IfcDoor elements.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgSectionHeight : public settings_detail::SettingBase<SvgSectionHeight, double> {
|
||||
static constexpr const char* const name = "section-height";
|
||||
static constexpr const char* const description = "Specifies the cut section height for SVG 2D geometry.";
|
||||
};
|
||||
|
||||
struct SvgSectionHeightFromStoreys : public settings_detail::SettingBase<SvgSectionHeightFromStoreys, bool> {
|
||||
static constexpr const char* const name = "section-height-from-storeys";
|
||||
static constexpr const char* const description = "Derives section height from storey elevation. Use --section-height to override the default offset of 1.2.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgPrintSpaceNames : public settings_detail::SettingBase<SvgPrintSpaceNames, bool> {
|
||||
static constexpr const char* const name = "print-space-names";
|
||||
static constexpr const char* const description = "Prints IfcSpace LongName and Name in the geometry output. Applicable for SVG output.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgPrintSpaceAreas : public settings_detail::SettingBase<SvgPrintSpaceAreas, bool> {
|
||||
static constexpr const char* const name = "print-space-areas";
|
||||
static constexpr const char* const description = "Prints calculated IfcSpace areas in square meters. Applicable for SVG output.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgSpaceNameTransform : public settings_detail::SettingBase<SvgSpaceNameTransform, std::string> {
|
||||
static constexpr const char* const name = "space-name-transform";
|
||||
static constexpr const char* const description = "Additional transform to the space labels in SVG.";
|
||||
};
|
||||
}
|
||||
|
||||
using geometry_setting_types = std::tuple<
|
||||
settings_detail::MesherLinearDeflection,
|
||||
settings_detail::MesherAngularDeflection,
|
||||
settings_detail::ReorientShells,
|
||||
settings_detail::LengthUnit,
|
||||
settings_detail::PlaneUnit,
|
||||
settings_detail::Precision,
|
||||
settings_detail::OutputDimensionality,
|
||||
settings_detail::LayersetFirst,
|
||||
settings_detail::DisableBooleanResult,
|
||||
settings_detail::NoWireIntersectionCheck,
|
||||
settings_detail::NoWireIntersectionTolerance,
|
||||
settings_detail::PrecisionFactor,
|
||||
settings_detail::DebugBooleanOperations,
|
||||
settings_detail::BooleanAttempt2d,
|
||||
settings_detail::SurfaceColour,
|
||||
settings_detail::WeldVertices,
|
||||
settings_detail::UseWorldCoords,
|
||||
settings_detail::UnifyShapes,
|
||||
settings_detail::UseMaterialNames,
|
||||
settings_detail::ConvertBackUnits,
|
||||
settings_detail::ContextIds,
|
||||
settings_detail::ContextTypes,
|
||||
settings_detail::ContextIdentifiers,
|
||||
settings_detail::ContextPriorities,
|
||||
settings_detail::IteratorOutput,
|
||||
settings_detail::DisableOpeningSubtractions,
|
||||
settings_detail::MaxVoidsPerElement,
|
||||
settings_detail::ApplyDefaultMaterials,
|
||||
settings_detail::DontEmitNormals,
|
||||
settings_detail::GenerateUvs,
|
||||
settings_detail::ApplyLayerSets,
|
||||
settings_detail::UseElementHierarchy,
|
||||
settings_detail::ValidateQuantities,
|
||||
settings_detail::EdgeArrows,
|
||||
settings_detail::BuildingLocalPlacement,
|
||||
settings_detail::SiteLocalPlacement,
|
||||
settings_detail::ForceSpaceTransparency,
|
||||
settings_detail::CircleSegments,
|
||||
settings_detail::CgalSmoothAngleDegrees,
|
||||
settings_detail::SvgRidgeAngleMinDegrees,
|
||||
settings_detail::SvgValleyAngleMinDegrees,
|
||||
settings_detail::SvgEmitFlushEdges,
|
||||
settings_detail::SvgUseEdgeClassification,
|
||||
settings_detail::SvgRenderCreaseEdges,
|
||||
settings_detail::SvgRenderSharpEdges,
|
||||
settings_detail::KeepBoundingBoxes,
|
||||
settings_detail::ComputeCurvature,
|
||||
settings_detail::FunctionStepType,
|
||||
settings_detail::FunctionStepParam,
|
||||
settings_detail::NoParallelMapping,
|
||||
settings_detail::PermissiveShapeReuse,
|
||||
settings_detail::ModelOffset,
|
||||
settings_detail::ModelRotation,
|
||||
settings_detail::TriangulationType,
|
||||
settings_detail::CgalEmitOriginalEdges,
|
||||
settings_detail::OcctNoCleanTriangulation,
|
||||
settings_detail::CacheShapes,
|
||||
settings_detail::DeferProcessingFirstElement,
|
||||
settings_detail::MaxOffset,
|
||||
settings_detail::MaxOffsetDeviation,
|
||||
settings_detail::ApplyOffset,
|
||||
settings_detail::MakeVolume,
|
||||
settings_detail::UseElementNames,
|
||||
settings_detail::UseElementGuids,
|
||||
settings_detail::UseElementStepIds,
|
||||
settings_detail::UseElementTypes,
|
||||
settings_detail::UseYUp,
|
||||
settings_detail::WriteGltfEcef,
|
||||
settings_detail::FloatingPointDigits,
|
||||
settings_detail::BaseUri,
|
||||
settings_detail::WktUseSection,
|
||||
settings_detail::SeparateZUpNode,
|
||||
settings_detail::SvgBounds,
|
||||
settings_detail::SvgScale,
|
||||
settings_detail::SvgCenter,
|
||||
settings_detail::SvgSectionRef,
|
||||
settings_detail::SvgElevationRef,
|
||||
settings_detail::SvgElevationRefGuid,
|
||||
settings_detail::SvgAutoSection,
|
||||
settings_detail::SvgAutoElevation,
|
||||
settings_detail::SvgDrawStoreyHeights,
|
||||
settings_detail::SvgProfileThreshold,
|
||||
settings_detail::SvgStoreyHeightLineLength,
|
||||
settings_detail::SvgUseNamespace,
|
||||
settings_detail::SvgUseHlrPoly,
|
||||
settings_detail::SvgUsePrefiltering,
|
||||
settings_detail::SvgUnifyInputs,
|
||||
settings_detail::SvgSegmentProjection,
|
||||
settings_detail::SvgSubtractBefore,
|
||||
settings_detail::SvgPolygonal,
|
||||
settings_detail::SvgAlwaysProject,
|
||||
settings_detail::SvgWithoutStoreys,
|
||||
settings_detail::SvgNoCss,
|
||||
settings_detail::SvgMirrorY,
|
||||
settings_detail::SvgMirrorX,
|
||||
settings_detail::SvgDoorArcs,
|
||||
settings_detail::SvgSectionHeight,
|
||||
settings_detail::SvgSectionHeightFromStoreys,
|
||||
settings_detail::SvgPrintSpaceNames,
|
||||
settings_detail::SvgPrintSpaceAreas,
|
||||
settings_detail::SvgSpaceNameTransform>;
|
||||
|
||||
class settings : public settings_container<geometry_setting_types> {
|
||||
public:
|
||||
using MesherLinearDeflection = settings_detail::MesherLinearDeflection;
|
||||
using MesherAngularDeflection = settings_detail::MesherAngularDeflection;
|
||||
using ReorientShells = settings_detail::ReorientShells;
|
||||
using LengthUnit = settings_detail::LengthUnit;
|
||||
using PlaneUnit = settings_detail::PlaneUnit;
|
||||
using Precision = settings_detail::Precision;
|
||||
using OutputDimensionality = settings_detail::OutputDimensionality;
|
||||
using LayersetFirst = settings_detail::LayersetFirst;
|
||||
using DisableBooleanResult = settings_detail::DisableBooleanResult;
|
||||
using NoWireIntersectionCheck = settings_detail::NoWireIntersectionCheck;
|
||||
using NoWireIntersectionTolerance = settings_detail::NoWireIntersectionTolerance;
|
||||
using PrecisionFactor = settings_detail::PrecisionFactor;
|
||||
using DebugBooleanOperations = settings_detail::DebugBooleanOperations;
|
||||
using BooleanAttempt2d = settings_detail::BooleanAttempt2d;
|
||||
using SurfaceColour = settings_detail::SurfaceColour;
|
||||
using WeldVertices = settings_detail::WeldVertices;
|
||||
using UseWorldCoords = settings_detail::UseWorldCoords;
|
||||
using UnifyShapes = settings_detail::UnifyShapes;
|
||||
using UseMaterialNames = settings_detail::UseMaterialNames;
|
||||
using ConvertBackUnits = settings_detail::ConvertBackUnits;
|
||||
using ContextIds = settings_detail::ContextIds;
|
||||
using ContextTypes = settings_detail::ContextTypes;
|
||||
using ContextIdentifiers = settings_detail::ContextIdentifiers;
|
||||
using ContextPriorities = settings_detail::ContextPriorities;
|
||||
using IteratorOutput = settings_detail::IteratorOutput;
|
||||
using DisableOpeningSubtractions = settings_detail::DisableOpeningSubtractions;
|
||||
using MaxVoidsPerElement = settings_detail::MaxVoidsPerElement;
|
||||
using ApplyDefaultMaterials = settings_detail::ApplyDefaultMaterials;
|
||||
using DontEmitNormals = settings_detail::DontEmitNormals;
|
||||
using GenerateUvs = settings_detail::GenerateUvs;
|
||||
using ApplyLayerSets = settings_detail::ApplyLayerSets;
|
||||
using UseElementHierarchy = settings_detail::UseElementHierarchy;
|
||||
using ValidateQuantities = settings_detail::ValidateQuantities;
|
||||
using EdgeArrows = settings_detail::EdgeArrows;
|
||||
using BuildingLocalPlacement = settings_detail::BuildingLocalPlacement;
|
||||
using SiteLocalPlacement = settings_detail::SiteLocalPlacement;
|
||||
using ForceSpaceTransparency = settings_detail::ForceSpaceTransparency;
|
||||
using CircleSegments = settings_detail::CircleSegments;
|
||||
using CgalSmoothAngleDegrees = settings_detail::CgalSmoothAngleDegrees;
|
||||
using SvgRidgeAngleMinDegrees = settings_detail::SvgRidgeAngleMinDegrees;
|
||||
using SvgValleyAngleMinDegrees = settings_detail::SvgValleyAngleMinDegrees;
|
||||
using SvgEmitFlushEdges = settings_detail::SvgEmitFlushEdges;
|
||||
using SvgUseEdgeClassification = settings_detail::SvgUseEdgeClassification;
|
||||
using SvgRenderCreaseEdges = settings_detail::SvgRenderCreaseEdges;
|
||||
using SvgRenderSharpEdges = settings_detail::SvgRenderSharpEdges;
|
||||
using KeepBoundingBoxes = settings_detail::KeepBoundingBoxes;
|
||||
using ComputeCurvature = settings_detail::ComputeCurvature;
|
||||
using FunctionStepType = settings_detail::FunctionStepType;
|
||||
using FunctionStepParam = settings_detail::FunctionStepParam;
|
||||
using NoParallelMapping = settings_detail::NoParallelMapping;
|
||||
using PermissiveShapeReuse = settings_detail::PermissiveShapeReuse;
|
||||
using ModelOffset = settings_detail::ModelOffset;
|
||||
using ModelRotation = settings_detail::ModelRotation;
|
||||
using TriangulationType = settings_detail::TriangulationType;
|
||||
using CgalEmitOriginalEdges = settings_detail::CgalEmitOriginalEdges;
|
||||
using OcctNoCleanTriangulation = settings_detail::OcctNoCleanTriangulation;
|
||||
using CacheShapes = settings_detail::CacheShapes;
|
||||
using DeferProcessingFirstElement = settings_detail::DeferProcessingFirstElement;
|
||||
using MaxOffset = settings_detail::MaxOffset;
|
||||
using MaxOffsetDeviation = settings_detail::MaxOffsetDeviation;
|
||||
using ApplyOffset = settings_detail::ApplyOffset;
|
||||
using MakeVolume = settings_detail::MakeVolume;
|
||||
|
||||
using UseElementNames = settings_detail::UseElementNames;
|
||||
using UseElementGuids = settings_detail::UseElementGuids;
|
||||
using UseElementStepIds = settings_detail::UseElementStepIds;
|
||||
using UseElementTypes = settings_detail::UseElementTypes;
|
||||
using UseYUp = settings_detail::UseYUp;
|
||||
using WriteGltfEcef = settings_detail::WriteGltfEcef;
|
||||
using FloatingPointDigits = settings_detail::FloatingPointDigits;
|
||||
using BaseUri = settings_detail::BaseUri;
|
||||
using WktUseSection = settings_detail::WktUseSection;
|
||||
using SeparateZUpNode = settings_detail::SeparateZUpNode;
|
||||
using SvgBounds = settings_detail::SvgBounds;
|
||||
using SvgScale = settings_detail::SvgScale;
|
||||
using SvgCenter = settings_detail::SvgCenter;
|
||||
using SvgSectionRef = settings_detail::SvgSectionRef;
|
||||
using SvgElevationRef = settings_detail::SvgElevationRef;
|
||||
using SvgElevationRefGuid = settings_detail::SvgElevationRefGuid;
|
||||
using SvgAutoSection = settings_detail::SvgAutoSection;
|
||||
using SvgAutoElevation = settings_detail::SvgAutoElevation;
|
||||
using SvgDrawStoreyHeights = settings_detail::SvgDrawStoreyHeights;
|
||||
using SvgProfileThreshold = settings_detail::SvgProfileThreshold;
|
||||
using SvgStoreyHeightLineLength = settings_detail::SvgStoreyHeightLineLength;
|
||||
using SvgUseNamespace = settings_detail::SvgUseNamespace;
|
||||
using SvgUseHlrPoly = settings_detail::SvgUseHlrPoly;
|
||||
using SvgUsePrefiltering = settings_detail::SvgUsePrefiltering;
|
||||
using SvgUnifyInputs = settings_detail::SvgUnifyInputs;
|
||||
using SvgSegmentProjection = settings_detail::SvgSegmentProjection;
|
||||
using SvgSubtractBefore = settings_detail::SvgSubtractBefore;
|
||||
using SvgPolygonal = settings_detail::SvgPolygonal;
|
||||
using SvgAlwaysProject = settings_detail::SvgAlwaysProject;
|
||||
using SvgWithoutStoreys = settings_detail::SvgWithoutStoreys;
|
||||
using SvgNoCss = settings_detail::SvgNoCss;
|
||||
using SvgMirrorY = settings_detail::SvgMirrorY;
|
||||
using SvgMirrorX = settings_detail::SvgMirrorX;
|
||||
using SvgDoorArcs = settings_detail::SvgDoorArcs;
|
||||
using SvgSectionHeight = settings_detail::SvgSectionHeight;
|
||||
using SvgSectionHeightFromStoreys = settings_detail::SvgSectionHeightFromStoreys;
|
||||
using SvgPrintSpaceNames = settings_detail::SvgPrintSpaceNames;
|
||||
using SvgPrintSpaceAreas = settings_detail::SvgPrintSpaceAreas;
|
||||
using SvgSpaceNameTransform = settings_detail::SvgSpaceNameTransform;
|
||||
|
||||
using OutputDimensionalityTypes = settings_detail::OutputDimensionalityTypes;
|
||||
using IteratorOutputOptions = settings_detail::IteratorOutputOptions;
|
||||
using FunctionStepMethod = settings_detail::FunctionStepMethod;
|
||||
using TriangulationMethod = settings_detail::TriangulationMethod;
|
||||
|
||||
static constexpr auto CURVES = settings_detail::CURVES;
|
||||
static constexpr auto SURFACES_AND_SOLIDS = settings_detail::SURFACES_AND_SOLIDS;
|
||||
static constexpr auto CURVES_SURFACES_AND_SOLIDS = settings_detail::CURVES_SURFACES_AND_SOLIDS;
|
||||
static constexpr auto TRIANGULATED = settings_detail::TRIANGULATED;
|
||||
static constexpr auto NATIVE = settings_detail::NATIVE;
|
||||
static constexpr auto SERIALIZED = settings_detail::SERIALIZED;
|
||||
static constexpr auto MAXSTEPSIZE = settings_detail::MAXSTEPSIZE;
|
||||
static constexpr auto MINSTEPS = settings_detail::MINSTEPS;
|
||||
static constexpr auto TRIANGLE_MESH = settings_detail::TRIANGLE_MESH;
|
||||
static constexpr auto POLYHEDRON_WITHOUT_HOLES = settings_detail::POLYHEDRON_WITHOUT_HOLES;
|
||||
static constexpr auto POLYHEDRON_WITH_HOLES = settings_detail::POLYHEDRON_WITH_HOLES;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// @todo find a place
|
||||
namespace IfcGeom {
|
||||
namespace ifcopenshell::geom {
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
|
||||
+39
-39
@@ -2,23 +2,23 @@
|
||||
|
||||
#include "../ifcgeom/IfcGeomElement.h"
|
||||
|
||||
using namespace ifcopenshell::geometry;
|
||||
using namespace ifcopenshell::geom;
|
||||
|
||||
ifcopenshell::geometry::Converter::Converter(std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel>&& geometry_library, ifcopenshell::file* file, ifcopenshell::geometry::Settings& s, ::logger& logger)
|
||||
ifcopenshell::geom::converter::converter(std::unique_ptr<ifcopenshell::geom::kernels::abstract_kernel>&& geometry_library, ifcopenshell::file* file, ifcopenshell::geom::settings& settings, ::logger& logger)
|
||||
: kernel_(std::move(geometry_library))
|
||||
, logger_(logger)
|
||||
{
|
||||
mapping_ = impl::mapping_implementations().construct(file, s, logger_);
|
||||
mapping_ = impl::mapping_implementations().construct(file, settings, logger_);
|
||||
// Mapping reads unit information and applies to settings
|
||||
settings_ = mapping_->settings();
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::Converter::~Converter() {
|
||||
ifcopenshell::geom::converter::~converter() {
|
||||
delete mapping_;
|
||||
}
|
||||
|
||||
namespace {
|
||||
void substitute_with_box_based_on_density(::logger& logger, IfcGeom::ConversionResults& items, double& density) {
|
||||
void substitute_with_box_based_on_density(::logger& logger, ifcopenshell::geom::conversion_results& items, double& density) {
|
||||
int nv = 0;
|
||||
void* box = nullptr;
|
||||
double volume = 0.;
|
||||
@@ -35,8 +35,8 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_representation_and_product(taxonomy::ptr representation_node, const express::Base product_, const taxonomy::matrix4::ptr& place_) {
|
||||
auto product = product_.as<express::Entity>();
|
||||
ifcopenshell::geom::brep_element* ifcopenshell::geom::converter::create_brep_for_representation_and_product(taxonomy::ptr representation_node, const express::base product_, const taxonomy::matrix4::ptr& place_) {
|
||||
auto product = product_.as<express::entity>();
|
||||
|
||||
std::stringstream representation_id_builder;
|
||||
|
||||
@@ -44,17 +44,17 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
|
||||
|
||||
representation_id_builder << representation_node->instance.id();
|
||||
|
||||
IfcGeom::Representation::BRep* shape;
|
||||
IfcGeom::ConversionResults shapes;
|
||||
ifcopenshell::geom::Representation::brep* shape;
|
||||
ifcopenshell::geom::conversion_results shapes;
|
||||
|
||||
if (!kernel_->convert(representation_node, shapes)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (settings_.get<ifcopenshell::geometry::settings::ApplyLayerSets>().get()) {
|
||||
ifcopenshell::geometry::layerset_information layerinfo;
|
||||
std::vector<ifcopenshell::geometry::endpoint_connection> neighbours;
|
||||
std::map<express::Base, ifcopenshell::geometry::layerset_information> neigbour_layers;
|
||||
if (settings_.get<ifcopenshell::geom::settings::ApplyLayerSets>().get()) {
|
||||
ifcopenshell::geom::layerset_information layerinfo;
|
||||
std::vector<ifcopenshell::geom::endpoint_connection> neighbours;
|
||||
std::map<express::base, ifcopenshell::geom::layerset_information> neigbour_layers;
|
||||
int layerset_id, lid;
|
||||
|
||||
if (mapping_->get_layerset_information(product, layerinfo, layerset_id)) {
|
||||
@@ -149,18 +149,18 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
|
||||
representation_id_builder << "-material-" << single_material.id();
|
||||
}
|
||||
|
||||
if (settings_.get<ifcopenshell::geometry::settings::ForceSpaceTransparency>().has() && product.declaration().is("IfcSpace")) {
|
||||
if (settings_.get<ifcopenshell::geom::settings::ForceSpaceTransparency>().has() && product.declaration().is("IfcSpace")) {
|
||||
for (auto& s : shapes) {
|
||||
if (s.hasStyle()) {
|
||||
// @todo the uglyness
|
||||
const_cast<taxonomy::style*>(&*s.StylePtr())->transparency = settings_.get<ifcopenshell::geometry::settings::ForceSpaceTransparency>().get();
|
||||
const_cast<taxonomy::style*>(&*s.StylePtr())->transparency = settings_.get<ifcopenshell::geom::settings::ForceSpaceTransparency>().get();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int parent_id = -1;
|
||||
try {
|
||||
express::Base parent_object = mapping_->get_decomposing_entity(product);
|
||||
express::base parent_object = mapping_->get_decomposing_entity(product);
|
||||
if (parent_object) {
|
||||
parent_id = parent_object.id();
|
||||
}
|
||||
@@ -178,8 +178,8 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
|
||||
auto openings = mapping_->find_openings(product);
|
||||
|
||||
const bool no_openings = openings.empty();
|
||||
const bool disable_opening_subtractions = settings_.get<ifcopenshell::geometry::settings::DisableOpeningSubtractions>().get();
|
||||
const bool above_limit = settings_.get<ifcopenshell::geometry::settings::MaxVoidsPerElement>().has() && settings_.get<ifcopenshell::geometry::settings::MaxVoidsPerElement>().get() != 0 && openings.size() > settings_.get<ifcopenshell::geometry::settings::MaxVoidsPerElement>().get();
|
||||
const bool disable_opening_subtractions = settings_.get<ifcopenshell::geom::settings::DisableOpeningSubtractions>().get();
|
||||
const bool above_limit = settings_.get<ifcopenshell::geom::settings::MaxVoidsPerElement>().has() && settings_.get<ifcopenshell::geom::settings::MaxVoidsPerElement>().get() != 0 && openings.size() > settings_.get<ifcopenshell::geom::settings::MaxVoidsPerElement>().get();
|
||||
|
||||
if (above_limit) {
|
||||
logger_.warning("GEO", 403, "Element has more openings than the maximum allowed. Openings will not be processed for this element:", product);
|
||||
@@ -191,12 +191,12 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
|
||||
representation_id_builder << "-" << op.id();
|
||||
}
|
||||
|
||||
IfcGeom::ConversionResults opened_shapes;
|
||||
ifcopenshell::geom::conversion_results opened_shapes;
|
||||
bool caught_error = false;
|
||||
try {
|
||||
std::vector<std::pair<taxonomy::ptr, taxonomy::matrix4>> opening_items;
|
||||
|
||||
std::transform(openings.begin(), openings.end(), std::back_inserter(opening_items), [this](express::Base opening) {
|
||||
std::transform(openings.begin(), openings.end(), std::back_inserter(opening_items), [this](express::base opening) {
|
||||
auto prod_item = mapping()->map(opening);
|
||||
auto repr = mapping()->representation_of(opening);
|
||||
if (repr) {
|
||||
@@ -226,25 +226,25 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
|
||||
}
|
||||
|
||||
if (!(caught_error && opened_shapes.size() < shapes.size())) {
|
||||
if (settings_.get<ifcopenshell::geometry::settings::UseWorldCoords>().get()) {
|
||||
if (settings_.get<ifcopenshell::geom::settings::UseWorldCoords>().get()) {
|
||||
for (auto it = opened_shapes.begin(); it != opened_shapes.end(); ++it) {
|
||||
it->prepend(place);
|
||||
}
|
||||
place = ifcopenshell::geometry::taxonomy::make<ifcopenshell::geometry::taxonomy::matrix4>();
|
||||
place = ifcopenshell::geom::taxonomy::make<ifcopenshell::geom::taxonomy::matrix4>();
|
||||
representation_id_builder << "-world-coords";
|
||||
}
|
||||
shapes = opened_shapes;
|
||||
}
|
||||
} else if (settings_.get<ifcopenshell::geometry::settings::UseWorldCoords>().get()) {
|
||||
} else if (settings_.get<ifcopenshell::geom::settings::UseWorldCoords>().get()) {
|
||||
for (auto it = shapes.begin(); it != shapes.end(); ++it) {
|
||||
it->prepend(place);
|
||||
}
|
||||
place = ifcopenshell::geometry::taxonomy::make<ifcopenshell::geometry::taxonomy::matrix4>();
|
||||
place = ifcopenshell::geom::taxonomy::make<ifcopenshell::geom::taxonomy::matrix4>();
|
||||
representation_id_builder << "-world-coords";
|
||||
}
|
||||
|
||||
if (settings_.get<ifcopenshell::geometry::settings::UnifyShapes>().get()) {
|
||||
IfcGeom::ConversionResults unified_shapes;
|
||||
if (settings_.get<ifcopenshell::geom::settings::UnifyShapes>().get()) {
|
||||
ifcopenshell::geom::conversion_results unified_shapes;
|
||||
try {
|
||||
if (kernel_->unify_shapes(shapes, unified_shapes)) {
|
||||
std::swap(shapes, unified_shapes);
|
||||
@@ -254,25 +254,25 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
|
||||
}
|
||||
}
|
||||
|
||||
shape = new IfcGeom::Representation::BRep(settings_, product_type, representation_id_builder.str(), shapes);
|
||||
shape = new ifcopenshell::geom::Representation::brep(settings_, product_type, representation_id_builder.str(), shapes);
|
||||
|
||||
std::string context_string = "";
|
||||
|
||||
// IfcShapeRepresentation.
|
||||
auto representation = representation_node->instance.as<express::Entity>();
|
||||
auto representation = representation_node->instance.as<express::entity>();
|
||||
auto representation_identifier = representation.get("RepresentationIdentifier");
|
||||
if (!representation_identifier.isNull()) {
|
||||
context_string = (std::string) representation_identifier;
|
||||
}
|
||||
else {
|
||||
auto context = (express::Base)representation.get("ContextOfItems");
|
||||
auto context_type = context.as<express::Entity>().get("ContextType");
|
||||
auto context = (express::base)representation.get("ContextOfItems");
|
||||
auto context_type = context.as<express::entity>().get("ContextType");
|
||||
if (!context_type.isNull()) {
|
||||
context_string = (std::string)context_type;
|
||||
}
|
||||
}
|
||||
|
||||
auto elem = new IfcGeom::BRepElement(
|
||||
auto elem = new ifcopenshell::geom::brep_element(
|
||||
product.id(),
|
||||
parent_id,
|
||||
name,
|
||||
@@ -280,7 +280,7 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
|
||||
guid,
|
||||
context_string,
|
||||
place,
|
||||
boost::shared_ptr<IfcGeom::Representation::BRep>(shape),
|
||||
boost::shared_ptr<ifcopenshell::geom::Representation::brep>(shape),
|
||||
product
|
||||
);
|
||||
|
||||
@@ -359,12 +359,12 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
|
||||
return elem;
|
||||
}
|
||||
|
||||
IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_processed_representation(const express::Base product_, const taxonomy::matrix4::ptr& place, IfcGeom::BRepElement* brep) {
|
||||
auto product = product_.as<express::Entity>();
|
||||
ifcopenshell::geom::brep_element* ifcopenshell::geom::converter::create_brep_for_processed_representation(const express::base product_, const taxonomy::matrix4::ptr& place, ifcopenshell::geom::brep_element* brep) {
|
||||
auto product = product_.as<express::entity>();
|
||||
|
||||
int parent_id = -1;
|
||||
try {
|
||||
express::Base parent_object = mapping_->get_decomposing_entity(product);
|
||||
express::base parent_object = mapping_->get_decomposing_entity(product);
|
||||
if (parent_object) {
|
||||
parent_id = parent_object.id();
|
||||
}
|
||||
@@ -377,7 +377,7 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_process
|
||||
const std::string product_type = product.declaration().name();
|
||||
const std::string context_string = brep->context();
|
||||
|
||||
return new IfcGeom::BRepElement(
|
||||
return new ifcopenshell::geom::brep_element(
|
||||
product.id(),
|
||||
parent_id,
|
||||
name,
|
||||
@@ -390,7 +390,7 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_process
|
||||
);
|
||||
}
|
||||
|
||||
IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_representation_and_product(const express::Base representation, const express::Base product) {
|
||||
ifcopenshell::geom::brep_element* ifcopenshell::geom::converter::create_brep_for_representation_and_product(const express::base representation, const express::base product) {
|
||||
auto interpreted_representation = mapping_->map(representation);
|
||||
if (!interpreted_representation) {
|
||||
interpreted_representation = taxonomy::make<taxonomy::collection>();
|
||||
@@ -403,11 +403,11 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
|
||||
);
|
||||
}
|
||||
|
||||
IfcGeom::ConversionResults ifcopenshell::geometry::Converter::convert(express::Base item)
|
||||
ifcopenshell::geom::conversion_results ifcopenshell::geom::converter::convert(express::base item)
|
||||
{
|
||||
std::clock_t map_start = std::clock();
|
||||
auto geom_item = mapping_->map(item);
|
||||
IfcGeom::ConversionResults results;
|
||||
ifcopenshell::geom::conversion_results results;
|
||||
if (geom_item) {
|
||||
std::clock_t geom_start = std::clock();
|
||||
if (!kernel_->convert(geom_item, results)) {
|
||||
|
||||
+19
-19
@@ -11,32 +11,32 @@
|
||||
|
||||
#include <boost/function.hpp>
|
||||
|
||||
namespace ifcopenshell { namespace geometry {
|
||||
namespace ifcopenshell { namespace geom {
|
||||
|
||||
class IFC_GEOM_API Converter {
|
||||
class IFC_GEOM_API converter {
|
||||
public:
|
||||
typedef boost::shared_ptr<IfcGeom::Representation::BRep> brep_ptr;
|
||||
typedef boost::shared_ptr<ifcopenshell::geom::Representation::brep> brep_ptr;
|
||||
private:
|
||||
ifcopenshell::geometry::abstract_mapping* mapping_;
|
||||
std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel> kernel_;
|
||||
ifcopenshell::geometry::Settings settings_;
|
||||
std::map<ifcopenshell::geometry::taxonomy::ptr, brep_ptr, ifcopenshell::geometry::taxonomy::less_functor> cache_;
|
||||
ifcopenshell::geom::abstract_mapping* mapping_;
|
||||
std::unique_ptr<ifcopenshell::geom::kernels::abstract_kernel> kernel_;
|
||||
ifcopenshell::geom::settings settings_;
|
||||
std::map<ifcopenshell::geom::taxonomy::ptr, brep_ptr, ifcopenshell::geom::taxonomy::less_functor> cache_;
|
||||
::logger& logger_;
|
||||
|
||||
public:
|
||||
ifcopenshell::geometry::kernels::AbstractKernel* kernel() { return &*kernel_; }
|
||||
ifcopenshell::geom::kernels::abstract_kernel* kernel() { return &*kernel_; }
|
||||
|
||||
Converter(std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel>&& geometry_library, ifcopenshell::file* file, ifcopenshell::geometry::Settings& settings, ::logger& logger = ::logger::root());
|
||||
converter(std::unique_ptr<ifcopenshell::geom::kernels::abstract_kernel>&& geometry_library, ifcopenshell::file* file, ifcopenshell::geom::settings& settings, ::logger& logger = ::logger::root());
|
||||
|
||||
~Converter();
|
||||
~converter();
|
||||
|
||||
ifcopenshell::geometry::abstract_mapping* mapping() const { return mapping_; }
|
||||
ifcopenshell::geom::abstract_mapping* mapping() const { return mapping_; }
|
||||
::logger& logger() const { return logger_; }
|
||||
|
||||
/*
|
||||
virtual NativeElement<double, double>* convert(
|
||||
const IteratorSettings& settings, express::Base representation,
|
||||
express::Base product)
|
||||
const IteratorSettings& settings, express::base representation,
|
||||
express::base product)
|
||||
{
|
||||
return implementation_->convert(settings, representation, product);
|
||||
}
|
||||
@@ -45,15 +45,15 @@ namespace ifcopenshell { namespace geometry {
|
||||
double total_map_time = 0.;
|
||||
double total_geom_time = 0.;
|
||||
|
||||
IfcGeom::ConversionResults convert(express::Base item);
|
||||
ifcopenshell::geom::conversion_results convert(express::base item);
|
||||
|
||||
IfcGeom::BRepElement* create_brep_for_representation_and_product(const express::Base representation, const express::Base product);
|
||||
// IfcGeom::BRepElement* create_brep_for_processed_representation(const express::Base representation, const express::Base product, IfcGeom::BRepElement* brep);
|
||||
ifcopenshell::geom::brep_element* create_brep_for_representation_and_product(const express::base representation, const express::base product);
|
||||
// ifcopenshell::geom::brep_element* create_brep_for_processed_representation(const express::base representation, const express::base product, ifcopenshell::geom::brep_element* brep);
|
||||
|
||||
IfcGeom::BRepElement* create_brep_for_representation_and_product(ifcopenshell::geometry::taxonomy::ptr, const express::Base product, const ifcopenshell::geometry::taxonomy::matrix4::ptr& place);
|
||||
IfcGeom::BRepElement* create_brep_for_processed_representation(const express::Base product, const ifcopenshell::geometry::taxonomy::matrix4::ptr& place, IfcGeom::BRepElement*);
|
||||
ifcopenshell::geom::brep_element* create_brep_for_representation_and_product(ifcopenshell::geom::taxonomy::ptr, const express::base product, const ifcopenshell::geom::taxonomy::matrix4::ptr& place);
|
||||
ifcopenshell::geom::brep_element* create_brep_for_processed_representation(const express::base product, const ifcopenshell::geom::taxonomy::matrix4::ptr& place, ifcopenshell::geom::brep_element*);
|
||||
|
||||
const ifcopenshell::geometry::Settings& settings() { return settings_; }
|
||||
const ifcopenshell::geom::settings& settings() { return settings_; }
|
||||
};
|
||||
}}
|
||||
|
||||
|
||||
@@ -25,280 +25,6 @@
|
||||
#include "../ifcparse/logger.h"
|
||||
#include <fstream>
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace geometry {
|
||||
inline namespace settings {
|
||||
|
||||
struct UseElementNames : public SettingBase<UseElementNames, bool> {
|
||||
static constexpr const char* const name = "use-element-names";
|
||||
static constexpr const char* const description = "Use entity instance IfcRoot.Name instead of unique IDs for naming elements upon serialization. Applicable for OBJ, DAE, STP, and SVG output.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct UseElementGuids : public SettingBase<UseElementGuids, bool> {
|
||||
static constexpr const char* const name = "use-element-guids";
|
||||
static constexpr const char* const description = "Use entity instance IfcRoot.GlobalId instead of unique IDs for naming elements upon serialization. Applicable for OBJ, DAE, STP, and SVG output.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct UseElementStepIds : public SettingBase<UseElementStepIds, bool> {
|
||||
static constexpr const char* const name = "use-element-step-ids";
|
||||
static constexpr const char* const description = "Use the numeric step identifier (entity instance name) for naming elements upon serialization. Applicable for OBJ, DAE, STP, and SVG output.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct UseElementTypes : public SettingBase<UseElementTypes, bool> {
|
||||
static constexpr const char* const name = "use-element-types";
|
||||
static constexpr const char* const description = "Use element types instead of unique IDs for naming elements upon serialization. Applicable to DAE output.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct UseYUp : public SettingBase<UseYUp, bool> {
|
||||
static constexpr const char* const name = "y-up";
|
||||
static constexpr const char* const description = "Change the 'up' axis to positive Y, default is Z UP. Applicable to OBJ output.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct WriteGltfEcef : public SettingBase<WriteGltfEcef, bool> {
|
||||
static constexpr const char* const name = "ecef";
|
||||
static constexpr const char* const description = "Write glTF in Earth-Centered Earth-Fixed coordinates. Requires PROJ.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct FloatingPointDigits : public SettingBase<FloatingPointDigits, int> {
|
||||
static constexpr const char* const name = "digits";
|
||||
static constexpr const char* const description = "Sets the precision to be used to format floating-point values, 15 by default. Use a negative value to use the system's default precision (should be 6 typically). Applicable for OBJ and DAE output. For DAE output, value >= 15 means that up to 16 decimals are used, and any other value means that 6 or 7 decimals are used.";
|
||||
static constexpr int defaultvalue = 15;
|
||||
};
|
||||
|
||||
struct BaseUri : public SettingBase<BaseUri, std::string> {
|
||||
static constexpr const char* const name = "base-uri";
|
||||
static constexpr const char* const description = "Base URI for products to be used in RDF-based serializations.";
|
||||
};
|
||||
|
||||
struct WktUseSection : public SettingBase<WktUseSection, bool> {
|
||||
static constexpr const char* const name = "wkt-use-section";
|
||||
static constexpr const char* const description = "Use a geometrical section rather than full polyhedral output and footprint in TTL WKT";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SeparateZUpNode : public SettingBase<SeparateZUpNode, bool> {
|
||||
static constexpr const char* const name = "separate-z-up-node";
|
||||
static constexpr const char* const description = "Introduce a separate Z-Up node into the GlTF hierarchy instead of multiplying the transform into the root node matrices";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgBounds : public SettingBase<SvgBounds, std::string> {
|
||||
static constexpr const char* const name = "bounds";
|
||||
static constexpr const char* const description = "Specifies the bounding rectangle, for example 512x512, to which the output will be scaled. Only used when converting to SVG.";
|
||||
};
|
||||
|
||||
struct SvgScale : public SettingBase<SvgScale, std::string> {
|
||||
static constexpr const char* const name = "scale";
|
||||
static constexpr const char* const description = "Interprets SVG bounds in mm, centers layout and draw elements to scale. Only used when converting to SVG. Example 1:100.";
|
||||
};
|
||||
|
||||
struct SvgCenter : public SettingBase<SvgCenter, std::string> {
|
||||
static constexpr const char* const name = "center";
|
||||
static constexpr const char* const description = "When using --scale, specifies the location in the range [0 1]x[0 1] around which to center the drawings. Example 0.5x0.5.";
|
||||
};
|
||||
|
||||
struct SvgSectionRef : public SettingBase<SvgSectionRef, std::string> {
|
||||
static constexpr const char* const name = "section-ref";
|
||||
static constexpr const char* const description = "Element at which cross sections should be created.";
|
||||
};
|
||||
|
||||
struct SvgElevationRef : public SettingBase<SvgElevationRef, std::string> {
|
||||
static constexpr const char* const name = "elevation-ref";
|
||||
static constexpr const char* const description = "Element at which drawings should be created.";
|
||||
};
|
||||
|
||||
struct SvgElevationRefGuid : public SettingBase<SvgElevationRefGuid, std::string> {
|
||||
static constexpr const char* const name = "elevation-ref-guid";
|
||||
static constexpr const char* const description = "Element guids at which drawings should be created.";
|
||||
};
|
||||
|
||||
struct SvgAutoSection : public SettingBase<SvgAutoSection, bool> {
|
||||
static constexpr const char* const name = "auto-section";
|
||||
static constexpr const char* const description = "Creates SVG cross section drawings automatically based on model extents.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgAutoElevation : public SettingBase<SvgAutoElevation, bool> {
|
||||
static constexpr const char* const name = "auto-elevation";
|
||||
static constexpr const char* const description = "Creates SVG elevation drawings automatically based on model extents.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgDrawStoreyHeights : public SettingBase<SvgDrawStoreyHeights, std::string> {
|
||||
static constexpr const char* const name = "draw-storey-heights";
|
||||
static constexpr const char* const description = "Draws a horizontal line at the height of building storeys in vertical drawings. Accepted values are none, full, and left.";
|
||||
};
|
||||
|
||||
struct SvgProfileThreshold : public SettingBase<SvgProfileThreshold, int> {
|
||||
static constexpr const char* const name = "profile-threshold";
|
||||
static constexpr const char* const description = "Limits the number of projected wire profiles for non-wall and non-slab elements in SVG output. A negative value disables the limit.";
|
||||
static constexpr int defaultvalue = -1;
|
||||
};
|
||||
|
||||
struct SvgStoreyHeightLineLength : public SettingBase<SvgStoreyHeightLineLength, double> {
|
||||
static constexpr const char* const name = "storey-height-line-length";
|
||||
static constexpr const char* const description = "Length of the line when --draw-storey-heights=left.";
|
||||
};
|
||||
|
||||
struct SvgUseNamespace : public SettingBase<SvgUseNamespace, bool> {
|
||||
static constexpr const char* const name = "svg-xmlns";
|
||||
static constexpr const char* const description = "Stores name and guid in a separate namespace as opposed to data-name, data-guid.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgUseHlrPoly : public SettingBase<SvgUseHlrPoly, bool> {
|
||||
static constexpr const char* const name = "svg-poly";
|
||||
static constexpr const char* const description = "Uses the polygonal algorithm for hidden line rendering.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgUsePrefiltering : public SettingBase<SvgUsePrefiltering, bool> {
|
||||
static constexpr const char* const name = "svg-prefilter";
|
||||
static constexpr const char* const description = "Prefilter faces and shapes before feeding to the hidden-line algorithm.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgUnifyInputs : public SettingBase<SvgUnifyInputs, bool> {
|
||||
static constexpr const char* const name = "svg-unify-inputs";
|
||||
static constexpr const char* const description = "Unify input shapes before SVG projection.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgSegmentProjection : public SettingBase<SvgSegmentProjection, bool> {
|
||||
static constexpr const char* const name = "svg-segment-projection";
|
||||
static constexpr const char* const description = "Segment result of projection with respect to original products.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgSubtractBefore : public SettingBase<SvgSubtractBefore, std::string> {
|
||||
static constexpr const char* const name = "svg-subtract-before";
|
||||
static constexpr const char* const description = "Controls which shapes are cut before SVG hidden-line projection. Accepted values are auto, slabs-and-walls, and always.";
|
||||
};
|
||||
|
||||
struct SvgPolygonal : public SettingBase<SvgPolygonal, bool> {
|
||||
static constexpr const char* const name = "svg-write-poly";
|
||||
static constexpr const char* const description = "Approximate every curve as polygonal in SVG output.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgAlwaysProject : public SettingBase<SvgAlwaysProject, bool> {
|
||||
static constexpr const char* const name = "svg-project";
|
||||
static constexpr const char* const description = "Always enable hidden line rendering instead of only on elevations.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgWithoutStoreys : public SettingBase<SvgWithoutStoreys, bool> {
|
||||
static constexpr const char* const name = "svg-without-storeys";
|
||||
static constexpr const char* const description = "Do not emit drawings for building storeys.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgNoCss : public SettingBase<SvgNoCss, bool> {
|
||||
static constexpr const char* const name = "svg-no-css";
|
||||
static constexpr const char* const description = "Do not emit CSS style declarations.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgMirrorY : public SettingBase<SvgMirrorY, bool> {
|
||||
static constexpr const char* const name = "svg-mirror-y";
|
||||
static constexpr const char* const description = "Mirror SVG output along the Y axis.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgMirrorX : public SettingBase<SvgMirrorX, bool> {
|
||||
static constexpr const char* const name = "svg-mirror-x";
|
||||
static constexpr const char* const description = "Mirror SVG output along the X axis.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgDoorArcs : public SettingBase<SvgDoorArcs, bool> {
|
||||
static constexpr const char* const name = "door-arcs";
|
||||
static constexpr const char* const description = "Draw door opening arcs for IfcDoor elements.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgSectionHeight : public SettingBase<SvgSectionHeight, double> {
|
||||
static constexpr const char* const name = "section-height";
|
||||
static constexpr const char* const description = "Specifies the cut section height for SVG 2D geometry.";
|
||||
};
|
||||
|
||||
struct SvgSectionHeightFromStoreys : public SettingBase<SvgSectionHeightFromStoreys, bool> {
|
||||
static constexpr const char* const name = "section-height-from-storeys";
|
||||
static constexpr const char* const description = "Derives section height from storey elevation. Use --section-height to override the default offset of 1.2.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgPrintSpaceNames : public SettingBase<SvgPrintSpaceNames, bool> {
|
||||
static constexpr const char* const name = "print-space-names";
|
||||
static constexpr const char* const description = "Prints IfcSpace LongName and Name in the geometry output. Applicable for SVG output.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgPrintSpaceAreas : public SettingBase<SvgPrintSpaceAreas, bool> {
|
||||
static constexpr const char* const name = "print-space-areas";
|
||||
static constexpr const char* const description = "Prints calculated IfcSpace areas in square meters. Applicable for SVG output.";
|
||||
static constexpr bool defaultvalue = false;
|
||||
};
|
||||
|
||||
struct SvgSpaceNameTransform : public SettingBase<SvgSpaceNameTransform, std::string> {
|
||||
static constexpr const char* const name = "space-name-transform";
|
||||
static constexpr const char* const description = "Additional transform to the space labels in SVG.";
|
||||
};
|
||||
}
|
||||
|
||||
class SerializerSettings : public SettingsContainer <
|
||||
// @todo should we use tuple_cat here to unify the settings into a single class?
|
||||
std::tuple<
|
||||
UseElementNames,
|
||||
UseElementGuids,
|
||||
UseElementStepIds,
|
||||
UseElementTypes,
|
||||
UseYUp,
|
||||
WriteGltfEcef,
|
||||
FloatingPointDigits,
|
||||
BaseUri,
|
||||
WktUseSection,
|
||||
SeparateZUpNode,
|
||||
SvgBounds,
|
||||
SvgScale,
|
||||
SvgCenter,
|
||||
SvgSectionRef,
|
||||
SvgElevationRef,
|
||||
SvgElevationRefGuid,
|
||||
SvgAutoSection,
|
||||
SvgAutoElevation,
|
||||
SvgDrawStoreyHeights,
|
||||
SvgProfileThreshold,
|
||||
SvgStoreyHeightLineLength,
|
||||
SvgUseNamespace,
|
||||
SvgUseHlrPoly,
|
||||
SvgUsePrefiltering,
|
||||
SvgUnifyInputs,
|
||||
SvgSegmentProjection,
|
||||
SvgSubtractBefore,
|
||||
SvgPolygonal,
|
||||
SvgAlwaysProject,
|
||||
SvgWithoutStoreys,
|
||||
SvgNoCss,
|
||||
SvgMirrorY,
|
||||
SvgMirrorX,
|
||||
SvgDoorArcs,
|
||||
SvgSectionHeight,
|
||||
SvgSectionHeightFromStoreys,
|
||||
SvgPrintSpaceNames,
|
||||
SvgPrintSpaceAreas,
|
||||
SvgSpaceNameTransform>>
|
||||
{};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class IFC_GEOM_API stream_or_filename {
|
||||
private:
|
||||
std::shared_ptr<std::ofstream> ofs_;
|
||||
@@ -336,48 +62,43 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class IFC_GEOM_API GeometrySerializer : public Serializer {
|
||||
class IFC_GEOM_API geometry_serializer : public serializer {
|
||||
public:
|
||||
enum read_type { READ_BREP, READ_TRIANGULATION };
|
||||
|
||||
GeometrySerializer(const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, ::logger* logger = nullptr)
|
||||
: Serializer(logger_or_root(logger))
|
||||
, geometry_settings_(geometry_settings)
|
||||
geometry_serializer(const ifcopenshell::geom::settings& settings, ::logger* logger = nullptr)
|
||||
: serializer(logger_or_root(logger))
|
||||
, settings_(settings)
|
||||
{}
|
||||
virtual ~GeometrySerializer() {}
|
||||
virtual ~geometry_serializer() {}
|
||||
|
||||
virtual bool isTesselated() const = 0;
|
||||
virtual void write(const IfcGeom::TriangulationElement* o) = 0;
|
||||
virtual void write(const IfcGeom::BRepElement* o) = 0;
|
||||
virtual void write(const ifcopenshell::geom::triangulation_element* o) = 0;
|
||||
virtual void write(const ifcopenshell::geom::brep_element* o) = 0;
|
||||
virtual void setUnitNameAndMagnitude(const std::string& name, float magnitude) = 0;
|
||||
virtual IfcGeom::Element* read(ifcopenshell::file& f, const std::string& guid, const std::string& representation_id, read_type rt = READ_BREP) = 0;
|
||||
virtual ifcopenshell::geom::element* read(ifcopenshell::file& f, const std::string& guid, const std::string& representation_id, read_type rt = READ_BREP) = 0;
|
||||
|
||||
const ifcopenshell::geometry::SerializerSettings& settings() const { return settings_; }
|
||||
ifcopenshell::geometry::SerializerSettings& settings() { return settings_; }
|
||||
|
||||
const ifcopenshell::geometry::Settings& geometry_settings() const { return geometry_settings_; }
|
||||
ifcopenshell::geometry::Settings& geometry_settings() { return geometry_settings_; }
|
||||
const ifcopenshell::geom::settings& settings() const { return settings_; }
|
||||
ifcopenshell::geom::settings& settings() { return settings_; }
|
||||
|
||||
/// Returns ID for the object depending on the used setting.
|
||||
virtual std::string object_id(const IfcGeom::Element* o)
|
||||
virtual std::string object_id(const ifcopenshell::geom::element* o)
|
||||
{
|
||||
if (settings_.get<ifcopenshell::geometry::settings::UseElementGuids>().get()) return o->guid();
|
||||
if (settings_.get<ifcopenshell::geometry::settings::UseElementNames>().get()) return o->name();
|
||||
if (settings_.get<ifcopenshell::geometry::settings::UseElementStepIds>().get()) return "id-" + boost::lexical_cast<std::string>(o->id());
|
||||
if (settings_.get<ifcopenshell::geom::settings::UseElementGuids>().get()) return o->guid();
|
||||
if (settings_.get<ifcopenshell::geom::settings::UseElementNames>().get()) return o->name();
|
||||
if (settings_.get<ifcopenshell::geom::settings::UseElementStepIds>().get()) return "id-" + boost::lexical_cast<std::string>(o->id());
|
||||
return o->unique_id();
|
||||
}
|
||||
|
||||
protected:
|
||||
ifcopenshell::geometry::Settings geometry_settings_;
|
||||
ifcopenshell::geometry::SerializerSettings settings_;
|
||||
ifcopenshell::geom::settings settings_;
|
||||
};
|
||||
|
||||
class IFC_GEOM_API WriteOnlyGeometrySerializer : public GeometrySerializer {
|
||||
class IFC_GEOM_API write_only_geometry_serializer : public geometry_serializer {
|
||||
public:
|
||||
WriteOnlyGeometrySerializer(const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, ::logger* logger = nullptr) : GeometrySerializer(geometry_settings, settings, logger) {}
|
||||
write_only_geometry_serializer(const ifcopenshell::geom::settings& settings, ::logger* logger = nullptr) : geometry_serializer(settings, logger) {}
|
||||
|
||||
virtual IfcGeom::Element* read(ifcopenshell::file&, const std::string&, const std::string&, read_type = READ_BREP) {
|
||||
virtual ifcopenshell::geom::element* read(ifcopenshell::file&, const std::string&, const std::string&, read_type = READ_BREP) {
|
||||
throw std::runtime_error("Not supported");
|
||||
};
|
||||
};
|
||||
|
||||
@@ -31,39 +31,39 @@
|
||||
#include "../ifcgeom/IfcGeomRepresentation.h"
|
||||
#include "../ifcgeom/ifc_geom_api.h"
|
||||
|
||||
namespace IfcGeom {
|
||||
namespace ifcopenshell::geom {
|
||||
|
||||
class Transformation {
|
||||
class transformation {
|
||||
private:
|
||||
ifcopenshell::geometry::Settings settings_;
|
||||
ifcopenshell::geometry::taxonomy::matrix4::ptr matrix_, matrix_orig_units_;
|
||||
ifcopenshell::geom::settings settings_;
|
||||
ifcopenshell::geom::taxonomy::matrix4::ptr matrix_, matrix_orig_units_;
|
||||
public:
|
||||
Transformation(const ifcopenshell::geometry::Settings& settings, const ifcopenshell::geometry::taxonomy::matrix4::ptr& matrix)
|
||||
transformation(const ifcopenshell::geom::settings& settings, const ifcopenshell::geom::taxonomy::matrix4::ptr& matrix)
|
||||
: settings_(settings), matrix_(matrix)
|
||||
{
|
||||
const bool convert = settings.get<ifcopenshell::geometry::settings::ConvertBackUnits>().get();
|
||||
auto unit_magnitude = settings.get<ifcopenshell::geometry::settings::LengthUnit>().get();
|
||||
const bool convert = settings.get<ifcopenshell::geom::settings::ConvertBackUnits>().get();
|
||||
auto unit_magnitude = settings.get<ifcopenshell::geom::settings::LengthUnit>().get();
|
||||
if (matrix_ && convert && unit_magnitude != 1.0) {
|
||||
matrix_orig_units_ = ifcopenshell::geometry::taxonomy::make<ifcopenshell::geometry::taxonomy::matrix4>(*matrix);
|
||||
matrix_orig_units_ = ifcopenshell::geom::taxonomy::make<ifcopenshell::geom::taxonomy::matrix4>(*matrix);
|
||||
// only multiple the translation components of the matrix with the unit magnitude, not the rotation/scaling components
|
||||
matrix_orig_units_->components().col(3).head<3>() /= unit_magnitude;
|
||||
} else {
|
||||
matrix_orig_units_ = nullptr;
|
||||
}
|
||||
}
|
||||
const ifcopenshell::geometry::taxonomy::matrix4::ptr& data() const {
|
||||
const ifcopenshell::geom::taxonomy::matrix4::ptr& data() const {
|
||||
if (matrix_orig_units_) {
|
||||
return matrix_orig_units_;
|
||||
}
|
||||
if (matrix_) {
|
||||
return matrix_;
|
||||
}
|
||||
static ifcopenshell::geometry::taxonomy::matrix4::ptr iden = ifcopenshell::geometry::taxonomy::make<ifcopenshell::geometry::taxonomy::matrix4>();
|
||||
static ifcopenshell::geom::taxonomy::matrix4::ptr iden = ifcopenshell::geom::taxonomy::make<ifcopenshell::geom::taxonomy::matrix4>();
|
||||
return iden;
|
||||
}
|
||||
};
|
||||
|
||||
class Element {
|
||||
class element {
|
||||
private:
|
||||
int _id;
|
||||
int _parent_id;
|
||||
@@ -72,17 +72,17 @@ namespace IfcGeom {
|
||||
std::string _guid;
|
||||
std::string _context;
|
||||
std::string _unique_id;
|
||||
Transformation _transformation;
|
||||
const express::Entity product_;
|
||||
std::vector<const IfcGeom::Element*> _parents;
|
||||
transformation _transformation;
|
||||
const express::entity product_;
|
||||
std::vector<const ifcopenshell::geom::element*> _parents;
|
||||
public:
|
||||
|
||||
friend bool operator == (const Element& element1, const Element& element2) {
|
||||
friend bool operator == (const element& element1, const element& element2) {
|
||||
return element1.id() == element2.id();
|
||||
}
|
||||
|
||||
// Use the id to compare, or the elevation is the elements are IfcBuildingStoreys and the elevation is set
|
||||
friend bool operator < (const Element& element1, const Element& element2) {
|
||||
friend bool operator < (const element& element1, const element& element2) {
|
||||
if (element1.type() == "IfcBuildingStorey" && element2.type() == "IfcBuildingStorey") {
|
||||
size_t attr_index = element1.product().declaration().as_entity()->attribute_index("Elevation");
|
||||
auto elev_attr1 = element1.product().get_attribute_value(attr_index);
|
||||
@@ -107,13 +107,13 @@ namespace IfcGeom {
|
||||
// Return the representation's identifier (e.g. "Body") if present, or it's context type (e.g. "Model").
|
||||
const std::string& context() const { return _context; }
|
||||
const std::string& unique_id() const { return _unique_id; }
|
||||
const Transformation& transformation() const { return _transformation; }
|
||||
const express::Entity& product() const { return product_; }
|
||||
const std::vector<const IfcGeom::Element*>& parents() const { return _parents; }
|
||||
void SetParents(std::vector<const IfcGeom::Element*>& newparents) { _parents = newparents; }
|
||||
const transformation& transformation() const { return _transformation; }
|
||||
const express::entity& product() const { return product_; }
|
||||
const std::vector<const ifcopenshell::geom::element*>& parents() const { return _parents; }
|
||||
void SetParents(std::vector<const ifcopenshell::geom::element*>& newparents) { _parents = newparents; }
|
||||
|
||||
Element(const ifcopenshell::geometry::Settings& settings, int id, int parent_id, const std::string& name, const std::string& type,
|
||||
const std::string& guid, const std::string& context, const ifcopenshell::geometry::taxonomy::matrix4::ptr& trsf, const express::Entity& product)
|
||||
element(const ifcopenshell::geom::settings& settings, int id, int parent_id, const std::string& name, const std::string& type,
|
||||
const std::string& guid, const std::string& context, const ifcopenshell::geom::taxonomy::matrix4::ptr& trsf, const express::entity& product)
|
||||
: _id(id), _parent_id(parent_id), _name(name), _type(type), _guid(guid), _context(context), _transformation(settings, trsf)
|
||||
, product_(product)
|
||||
{
|
||||
@@ -139,19 +139,19 @@ namespace IfcGeom {
|
||||
|
||||
_unique_id = oss.str();
|
||||
}
|
||||
virtual ~Element() {}
|
||||
virtual ~element() {}
|
||||
};
|
||||
|
||||
class BRepElement : public Element {
|
||||
class brep_element : public element {
|
||||
private:
|
||||
boost::shared_ptr<IfcGeom::Representation::BRep> _geometry;
|
||||
boost::shared_ptr<ifcopenshell::geom::Representation::brep> _geometry;
|
||||
public:
|
||||
const boost::shared_ptr<IfcGeom::Representation::BRep>& geometry_pointer() const { return _geometry; }
|
||||
const IfcGeom::Representation::BRep& geometry() const { return *_geometry; }
|
||||
BRepElement(int id, int parent_id, const std::string& name, const std::string& type, const std::string& guid,
|
||||
const std::string& context, const ifcopenshell::geometry::taxonomy::matrix4::ptr& trsf, const boost::shared_ptr<IfcGeom::Representation::BRep>& geometry,
|
||||
const express::Entity& product)
|
||||
: Element(geometry->settings(), id, parent_id, name, type, guid, context, trsf, product)
|
||||
const boost::shared_ptr<ifcopenshell::geom::Representation::brep>& geometry_pointer() const { return _geometry; }
|
||||
const ifcopenshell::geom::Representation::brep& geometry() const { return *_geometry; }
|
||||
brep_element(int id, int parent_id, const std::string& name, const std::string& type, const std::string& guid,
|
||||
const std::string& context, const ifcopenshell::geom::taxonomy::matrix4::ptr& trsf, const boost::shared_ptr<ifcopenshell::geom::Representation::brep>& geometry,
|
||||
const express::entity& product)
|
||||
: element(geometry->settings(), id, parent_id, name, type, guid, context, trsf, product)
|
||||
, _geometry(geometry)
|
||||
{}
|
||||
|
||||
@@ -159,44 +159,44 @@ namespace IfcGeom {
|
||||
return geometry().calculate_projected_surface_area(this->transformation().data(), along_x, along_y, along_z);
|
||||
}
|
||||
private:
|
||||
BRepElement(const BRepElement& other);
|
||||
BRepElement& operator=(const BRepElement& other);
|
||||
brep_element(const brep_element& other);
|
||||
brep_element& operator=(const brep_element& other);
|
||||
};
|
||||
|
||||
class TriangulationElement : public Element {
|
||||
class triangulation_element : public element {
|
||||
private:
|
||||
boost::shared_ptr< IfcGeom::Representation::Triangulation > _geometry;
|
||||
boost::shared_ptr< ifcopenshell::geom::Representation::triangulation > _geometry;
|
||||
public:
|
||||
const IfcGeom::Representation::Triangulation& geometry() const { return *_geometry; }
|
||||
const boost::shared_ptr< IfcGeom::Representation::Triangulation>& geometry_pointer() const { return _geometry; }
|
||||
TriangulationElement(const IfcGeom::BRepElement& shape_model)
|
||||
: Element(shape_model)
|
||||
, _geometry(boost::shared_ptr<IfcGeom::Representation::Triangulation>(new IfcGeom::Representation::Triangulation(shape_model.geometry())))
|
||||
const ifcopenshell::geom::Representation::triangulation& geometry() const { return *_geometry; }
|
||||
const boost::shared_ptr< ifcopenshell::geom::Representation::triangulation>& geometry_pointer() const { return _geometry; }
|
||||
triangulation_element(const ifcopenshell::geom::brep_element& shape_model)
|
||||
: element(shape_model)
|
||||
, _geometry(boost::shared_ptr<ifcopenshell::geom::Representation::triangulation>(new ifcopenshell::geom::Representation::triangulation(shape_model.geometry())))
|
||||
{}
|
||||
TriangulationElement(const IfcGeom::Element& element, const boost::shared_ptr<IfcGeom::Representation::Triangulation>& geometry)
|
||||
: Element(element)
|
||||
triangulation_element(const ifcopenshell::geom::element& element, const boost::shared_ptr<ifcopenshell::geom::Representation::triangulation>& geometry)
|
||||
: element(element)
|
||||
, _geometry(geometry)
|
||||
{}
|
||||
private:
|
||||
TriangulationElement(const TriangulationElement& other);
|
||||
TriangulationElement& operator=(const TriangulationElement& other);
|
||||
triangulation_element(const triangulation_element& other);
|
||||
triangulation_element& operator=(const triangulation_element& other);
|
||||
};
|
||||
|
||||
class SerializedElement : public Element {
|
||||
class serialized_element : public element {
|
||||
private:
|
||||
IfcGeom::Representation::Serialization* _geometry;
|
||||
ifcopenshell::geom::Representation::serialization* _geometry;
|
||||
public:
|
||||
const IfcGeom::Representation::Serialization& geometry() const { return *_geometry; }
|
||||
SerializedElement(const BRepElement& shape_model)
|
||||
: Element(shape_model)
|
||||
, _geometry(new IfcGeom::Representation::Serialization(shape_model.geometry()))
|
||||
const ifcopenshell::geom::Representation::serialization& geometry() const { return *_geometry; }
|
||||
serialized_element(const brep_element& shape_model)
|
||||
: element(shape_model)
|
||||
, _geometry(new ifcopenshell::geom::Representation::serialization(shape_model.geometry()))
|
||||
{}
|
||||
virtual ~SerializedElement() {
|
||||
virtual ~serialized_element() {
|
||||
delete _geometry;
|
||||
}
|
||||
private:
|
||||
SerializedElement(const SerializedElement& other);
|
||||
SerializedElement& operator=(const SerializedElement& other);
|
||||
serialized_element(const serialized_element& other);
|
||||
serialized_element& operator=(const serialized_element& other);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+20
-20
@@ -18,7 +18,7 @@
|
||||
********************************************************************************/
|
||||
|
||||
/** @file IfcGeomFilter.h
|
||||
@brief A set of predefined product filters for IfcGeom::Iterator */
|
||||
@brief A set of predefined product filters for ifcopenshell::geom::iterator */
|
||||
|
||||
#ifndef IFCGEOMFILTER_H
|
||||
#define IFCGEOMFILTER_H
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace IfcGeom {
|
||||
namespace ifcopenshell::geom {
|
||||
|
||||
struct filter
|
||||
{
|
||||
@@ -56,7 +56,7 @@ namespace IfcGeom {
|
||||
/// Optional description for the filtering criteria of this filter.
|
||||
std::string description;
|
||||
|
||||
bool match(const express::Base& prod, const ifcopenshell::geometry::filter_t& pred) const {
|
||||
bool match(const express::base& prod, const ifcopenshell::geom::filter_t& pred) const {
|
||||
bool is_match = pred(prod);
|
||||
if (!is_match && traverse) {
|
||||
is_match = traverse_match(prod, pred);
|
||||
@@ -64,15 +64,15 @@ namespace IfcGeom {
|
||||
return is_match == include;
|
||||
}
|
||||
|
||||
bool traverse_match(const express::Base& prod, const ifcopenshell::geometry::filter_t& pred) const
|
||||
bool traverse_match(const express::base& prod, const ifcopenshell::geom::filter_t& pred) const
|
||||
{
|
||||
express::Base parent, current = prod;
|
||||
express::base parent, current = prod;
|
||||
// @todo examine if this can indeed be static. For now usage is only
|
||||
// in IfcConvert so invocation is bound to a single file with a single
|
||||
// schema.
|
||||
// @todo pass settings
|
||||
ifcopenshell::geometry::Settings s;
|
||||
static auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(prod.file(), s);
|
||||
ifcopenshell::geom::settings s;
|
||||
static auto mapping = ifcopenshell::geom::impl::mapping_implementations().construct(prod.file(), s);
|
||||
while ((parent = mapping->get_decomposing_entity(current, traverse_openings))) {
|
||||
if (pred(parent)) {
|
||||
return true;
|
||||
@@ -132,9 +132,9 @@ namespace IfcGeom {
|
||||
attribute_filter(const std::string& attribute_name)
|
||||
: attribute_name(attribute_name) {}
|
||||
|
||||
std::string value(const express::Base& prod) const {
|
||||
std::string value(const express::base& prod) const {
|
||||
try {
|
||||
return (std::string) prod.as<express::Entity>().get(attribute_name);
|
||||
return (std::string) prod.as<express::entity>().get(attribute_name);
|
||||
} catch (...) {
|
||||
// Either
|
||||
// (a) not an attribute name for this entity instance
|
||||
@@ -146,11 +146,11 @@ namespace IfcGeom {
|
||||
}
|
||||
}
|
||||
|
||||
bool match(express::Base prod) const {
|
||||
bool match(express::base prod) const {
|
||||
return wildcard_filter::match(value(prod));
|
||||
}
|
||||
|
||||
bool operator()(express::Base prod) const {
|
||||
bool operator()(express::base prod) const {
|
||||
return filter::match(prod, std::bind(&attribute_filter::match, this, std::placeholders::_1));
|
||||
}
|
||||
|
||||
@@ -171,21 +171,21 @@ namespace IfcGeom {
|
||||
};
|
||||
|
||||
struct layer_filter : public wildcard_filter {
|
||||
typedef std::map<std::string, express::Base> layer_map_t;
|
||||
typedef std::map<std::string, express::base> layer_map_t;
|
||||
|
||||
layer_filter() {}
|
||||
layer_filter(bool include, bool traverse, const std::set<std::string>& patterns)
|
||||
: wildcard_filter(include, traverse, patterns) {}
|
||||
|
||||
bool match(express::Base prod) const {
|
||||
bool match(express::base prod) const {
|
||||
// @todo
|
||||
ifcopenshell::geometry::Settings s;
|
||||
static auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(prod.file(), s);
|
||||
ifcopenshell::geom::settings s;
|
||||
static auto mapping = ifcopenshell::geom::impl::mapping_implementations().construct(prod.file(), s);
|
||||
layer_map_t layers = mapping->get_layers(prod);
|
||||
return std::find_if(layers.begin(), layers.end(), wildcards_match(values)) != layers.end();
|
||||
}
|
||||
|
||||
bool operator()(express::Base prod) const {
|
||||
bool operator()(express::base prod) const {
|
||||
return filter::match(prod, std::bind(&layer_filter::match, this, std::placeholders::_1));
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ namespace IfcGeom {
|
||||
: filter(include, traverse)
|
||||
, entity_names(entity_names) {}
|
||||
|
||||
bool match(express::Base prod) const {
|
||||
bool match(express::base prod) const {
|
||||
// The set is iterated over to able to filter on subtypes.
|
||||
for (auto& name : entity_names) {
|
||||
if (prod.declaration().is(name)) {
|
||||
@@ -228,7 +228,7 @@ namespace IfcGeom {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator()(express::Base prod) const {
|
||||
bool operator()(express::base prod) const {
|
||||
return filter::match(prod, std::bind(&entity_filter::match, this, std::placeholders::_1));
|
||||
}
|
||||
|
||||
@@ -250,11 +250,11 @@ namespace IfcGeom {
|
||||
: filter(include, traverse)
|
||||
, instance_ids_(instance_ids) {}
|
||||
|
||||
bool match(express::Base prod) const {
|
||||
bool match(express::base prod) const {
|
||||
return instance_ids_.find(prod.id()) != instance_ids_.end();
|
||||
}
|
||||
|
||||
bool operator()(express::Base prod) const {
|
||||
bool operator()(express::base prod) const {
|
||||
return filter::match(prod, std::bind(&instance_id_filter::match, this, std::placeholders::_1));
|
||||
}
|
||||
|
||||
|
||||
@@ -30,10 +30,10 @@
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
|
||||
namespace IfcGeom {
|
||||
IFC_GEOM_API const ifcopenshell::geometry::taxonomy::style::ptr& get_default_style(const std::string& ifc_type);
|
||||
namespace ifcopenshell::geom {
|
||||
IFC_GEOM_API const ifcopenshell::geom::taxonomy::style::ptr& get_default_style(const std::string& ifc_type);
|
||||
|
||||
IFC_GEOM_API ifcopenshell::geometry::taxonomy::style::ptr& update_default_style(const std::string& ifc_type);
|
||||
IFC_GEOM_API ifcopenshell::geom::taxonomy::style::ptr& update_default_style(const std::string& ifc_type);
|
||||
|
||||
IFC_GEOM_API void set_default_style_file(const std::string& json_file);
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
|
||||
#include "IfcGeomRepresentation.h"
|
||||
|
||||
IfcGeom::Representation::Serialization::Serialization(const BRep& brep)
|
||||
: Representation(brep.settings(), brep.entity(), brep.id())
|
||||
ifcopenshell::geom::Representation::serialization::serialization(const brep& brep)
|
||||
: representation(brep.settings(), brep.entity(), brep.id())
|
||||
{
|
||||
for (auto it = brep.begin(); it != brep.end(); ++it) {
|
||||
int sid = -1;
|
||||
@@ -47,19 +47,19 @@ IfcGeom::Representation::Serialization::Serialization(const BRep& brep)
|
||||
surface_style_ids_.push_back(sid);
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::taxonomy::matrix4 identity;
|
||||
ifcopenshell::geom::taxonomy::matrix4 identity;
|
||||
auto* comp = brep.as_compound();
|
||||
comp->Serialize(identity, brep_data_);
|
||||
delete comp;
|
||||
}
|
||||
|
||||
IfcGeom::ConversionResultShape* IfcGeom::Representation::BRep::as_compound(bool force_meters) const {
|
||||
ConversionResultShape* accum = nullptr;
|
||||
ifcopenshell::geom::conversion_result_shape* ifcopenshell::geom::Representation::brep::as_compound(bool force_meters) const {
|
||||
conversion_result_shape* accum = nullptr;
|
||||
|
||||
for (auto it = begin(); it != end(); ++it) {
|
||||
double unit_scale = 1.0;
|
||||
if (!force_meters && settings().get<ifcopenshell::geometry::settings::ConvertBackUnits>().get()) {
|
||||
unit_scale = 1.0 / settings().get<ifcopenshell::geometry::settings::LengthUnit>().get();
|
||||
if (!force_meters && settings().get<ifcopenshell::geom::settings::ConvertBackUnits>().get()) {
|
||||
unit_scale = 1.0 / settings().get<ifcopenshell::geom::settings::LengthUnit>().get();
|
||||
}
|
||||
auto s = it->apply_transform(unit_scale);
|
||||
if (accum) {
|
||||
@@ -75,8 +75,8 @@ IfcGeom::ConversionResultShape* IfcGeom::Representation::BRep::as_compound(bool
|
||||
return accum;
|
||||
}
|
||||
|
||||
bool IfcGeom::Representation::BRep::calculate_surface_area(double& area) const {
|
||||
std::unique_ptr<ConversionResultShape> s(as_compound());
|
||||
bool ifcopenshell::geom::Representation::brep::calculate_surface_area(double& area) const {
|
||||
std::unique_ptr<conversion_result_shape> s(as_compound());
|
||||
if (!s) {
|
||||
area = 0.;
|
||||
return false;
|
||||
@@ -85,8 +85,8 @@ bool IfcGeom::Representation::BRep::calculate_surface_area(double& area) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::Representation::BRep::calculate_volume(double& volume) const {
|
||||
std::unique_ptr<ConversionResultShape> s(as_compound());
|
||||
bool ifcopenshell::geom::Representation::brep::calculate_volume(double& volume) const {
|
||||
std::unique_ptr<conversion_result_shape> s(as_compound());
|
||||
if (!s) {
|
||||
volume = 0.;
|
||||
return false;
|
||||
@@ -95,12 +95,12 @@ bool IfcGeom::Representation::BRep::calculate_volume(double& volume) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::Representation::BRep::calculate_projected_surface_area(const ifcopenshell::geometry::taxonomy::matrix4::ptr& place, double& along_x, double& along_y, double& along_z) const {
|
||||
bool ifcopenshell::geom::Representation::brep::calculate_projected_surface_area(const ifcopenshell::geom::taxonomy::matrix4::ptr& place, double& along_x, double& along_y, double& along_z) const {
|
||||
along_x = along_y = along_z = 0.;
|
||||
|
||||
for (IfcGeom::ConversionResults::const_iterator it = begin(); it != end(); ++it) {
|
||||
for (ifcopenshell::geom::conversion_results::const_iterator it = begin(); it != end(); ++it) {
|
||||
double x, y, z;
|
||||
it->Shape()->surface_area_along_direction(settings().get<ifcopenshell::geometry::settings::MesherLinearDeflection>().get(), place, x, y, z);
|
||||
it->Shape()->surface_area_along_direction(settings().get<ifcopenshell::geom::settings::MesherLinearDeflection>().get(), place, x, y, z);
|
||||
|
||||
if (it->Shape()->is_manifold()) {
|
||||
x /= 2.;
|
||||
@@ -116,11 +116,11 @@ bool IfcGeom::Representation::BRep::calculate_projected_surface_area(const ifcop
|
||||
return true;
|
||||
}
|
||||
|
||||
IfcGeom::Representation::Triangulation::Triangulation(const BRep& shape_model)
|
||||
: Representation(shape_model.settings(), shape_model.entity(), shape_model.id())
|
||||
ifcopenshell::geom::Representation::triangulation::triangulation(const brep& shape_model)
|
||||
: representation(shape_model.settings(), shape_model.entity(), shape_model.id())
|
||||
, weld_offset_(0)
|
||||
{
|
||||
for (IfcGeom::ConversionResults::const_iterator iit = shape_model.begin(); iit != shape_model.end(); ++iit) {
|
||||
for (ifcopenshell::geom::conversion_results::const_iterator iit = shape_model.begin(); iit != shape_model.end(); ++iit) {
|
||||
|
||||
// Don't weld vertices that belong to different items to prevent non-manifold situations.
|
||||
resetWelds();
|
||||
@@ -136,8 +136,8 @@ IfcGeom::Representation::Triangulation::Triangulation(const BRep& shape_model)
|
||||
}
|
||||
}
|
||||
|
||||
if (settings().get<ifcopenshell::geometry::settings::ApplyDefaultMaterials>().get() && surface_style_id == -1) {
|
||||
const auto& material = IfcGeom::get_default_style(shape_model.entity());
|
||||
if (settings().get<ifcopenshell::geom::settings::ApplyDefaultMaterials>().get() && surface_style_id == -1) {
|
||||
const auto& material = ifcopenshell::geom::get_default_style(shape_model.entity());
|
||||
auto mit = std::find(materials_.begin(), materials_.end(), material);
|
||||
if (mit == materials_.end()) {
|
||||
surface_style_id = (int)materials_.size();
|
||||
@@ -154,7 +154,7 @@ IfcGeom::Representation::Triangulation::Triangulation(const BRep& shape_model)
|
||||
/// Generates UVs for a single mesh using box projection.
|
||||
/// @todo Very simple impl. Assumes that input vertices and normals match 1:1.
|
||||
|
||||
std::vector<double> IfcGeom::Representation::Triangulation::box_project_uvs(const std::vector<double>& vertices, const std::vector<double>& normals)
|
||||
std::vector<double> ifcopenshell::geom::Representation::triangulation::box_project_uvs(const std::vector<double>& vertices, const std::vector<double>& normals)
|
||||
{
|
||||
std::vector<double> uvs;
|
||||
uvs.resize(vertices.size() / 3 * 2);
|
||||
@@ -182,16 +182,16 @@ std::vector<double> IfcGeom::Representation::Triangulation::box_project_uvs(cons
|
||||
return uvs;
|
||||
}
|
||||
|
||||
int IfcGeom::Representation::Triangulation::addVertex(int item_id, int material_index, double pX, double pY, double pZ) {
|
||||
const bool convert = settings().get<ifcopenshell::geometry::settings::ConvertBackUnits>().get();
|
||||
auto unit_magnitude = settings().get<ifcopenshell::geometry::settings::LengthUnit>().get();
|
||||
int ifcopenshell::geom::Representation::triangulation::addVertex(int item_id, int material_index, double pX, double pY, double pZ) {
|
||||
const bool convert = settings().get<ifcopenshell::geom::settings::ConvertBackUnits>().get();
|
||||
auto unit_magnitude = settings().get<ifcopenshell::geom::settings::LengthUnit>().get();
|
||||
const double X = convert ? (pX /unit_magnitude) : pX;
|
||||
const double Y = convert ? (pY /unit_magnitude) : pY;
|
||||
const double Z = convert ? (pZ /unit_magnitude) : pZ;
|
||||
int i = (int)verts_.size() / 3;
|
||||
if (settings().get<ifcopenshell::geometry::settings::WeldVertices>().get()) {
|
||||
const VertexKey key = std::make_tuple(item_id, material_index, X, Y, Z);
|
||||
typename VertexKeyMap::const_iterator it = welds.find(key);
|
||||
if (settings().get<ifcopenshell::geom::settings::WeldVertices>().get()) {
|
||||
const vertex_key key = std::make_tuple(item_id, material_index, X, Y, Z);
|
||||
typename vertex_key_map::const_iterator it = welds.find(key);
|
||||
if (it != welds.end()) {
|
||||
// Return index for previously encountered point
|
||||
return it->second;
|
||||
@@ -205,12 +205,12 @@ int IfcGeom::Representation::Triangulation::addVertex(int item_id, int material_
|
||||
return i;
|
||||
}
|
||||
|
||||
void IfcGeom::Representation::Triangulation::registerEdgeCount(int n1, int n2, std::map<std::pair<int, int>, int>& edgecount) {
|
||||
const Edge e = Edge((std::min)(n1, n2), (std::max)(n1, n2));
|
||||
void ifcopenshell::geom::Representation::triangulation::registerEdgeCount(int n1, int n2, std::map<std::pair<int, int>, int>& edgecount) {
|
||||
const edge e = edge((std::min)(n1, n2), (std::max)(n1, n2));
|
||||
edgecount[e] ++;
|
||||
}
|
||||
|
||||
const IfcGeom::ConversionResultShape* IfcGeom::Representation::BRep::item(int i) const {
|
||||
const ifcopenshell::geom::conversion_result_shape* ifcopenshell::geom::Representation::brep::item(int i) const {
|
||||
if (i >= 0 && i < shapes_.size()) {
|
||||
return shapes_[i].Shape()->moved(shapes_[i].Placement());
|
||||
} else {
|
||||
@@ -218,7 +218,7 @@ const IfcGeom::ConversionResultShape* IfcGeom::Representation::BRep::item(int i)
|
||||
}
|
||||
}
|
||||
|
||||
int IfcGeom::Representation::BRep::item_id(int i) const {
|
||||
int ifcopenshell::geom::Representation::brep::item_id(int i) const {
|
||||
if (i >= 0 && i < shapes_.size()) {
|
||||
return shapes_[i].ItemId();
|
||||
} else {
|
||||
|
||||
@@ -25,24 +25,24 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace IfcGeom {
|
||||
namespace ifcopenshell::geom {
|
||||
|
||||
namespace Representation {
|
||||
|
||||
class IFC_GEOM_API Representation {
|
||||
Representation(const Representation&); //N/A
|
||||
Representation& operator =(const Representation&); //N/A
|
||||
class IFC_GEOM_API representation {
|
||||
representation(const representation&); //N/A
|
||||
representation& operator =(const representation&); //N/A
|
||||
protected:
|
||||
const ifcopenshell::geometry::Settings settings_;
|
||||
const ifcopenshell::geom::settings settings_;
|
||||
const std::string entity_;
|
||||
std::string id_;
|
||||
public:
|
||||
explicit Representation(const ifcopenshell::geometry::Settings& settings, const std::string& entity, const std::string& id)
|
||||
explicit representation(const ifcopenshell::geom::settings& settings, const std::string& entity, const std::string& id)
|
||||
: settings_(settings)
|
||||
, entity_(entity)
|
||||
, id_(id)
|
||||
{}
|
||||
const ifcopenshell::geometry::Settings& settings() const { return settings_; }
|
||||
const ifcopenshell::geom::settings& settings() const { return settings_; }
|
||||
const std::string& entity() const {
|
||||
return entity_;
|
||||
}
|
||||
@@ -51,35 +51,35 @@ namespace IfcGeom {
|
||||
// - material-material_id
|
||||
// - openings-opening0_id-...-openingN_id
|
||||
const std::string& id() const { return id_; }
|
||||
virtual ~Representation() {}
|
||||
virtual ~representation() {}
|
||||
};
|
||||
|
||||
class IFC_GEOM_API BRep : public Representation {
|
||||
class IFC_GEOM_API brep : public representation {
|
||||
private:
|
||||
const IfcGeom::ConversionResults shapes_;
|
||||
BRep(const BRep& other);
|
||||
BRep& operator=(const BRep& other);
|
||||
const ifcopenshell::geom::conversion_results shapes_;
|
||||
brep(const brep& other);
|
||||
brep& operator=(const brep& other);
|
||||
public:
|
||||
BRep(const ifcopenshell::geometry::Settings& settings, const std::string& entity, const std::string& id, const IfcGeom::ConversionResults& shapes)
|
||||
: Representation(settings, entity, id)
|
||||
brep(const ifcopenshell::geom::settings& settings, const std::string& entity, const std::string& id, const ifcopenshell::geom::conversion_results& shapes)
|
||||
: representation(settings, entity, id)
|
||||
, shapes_(shapes)
|
||||
{}
|
||||
virtual ~BRep() {}
|
||||
IfcGeom::ConversionResults::const_iterator begin() const { return shapes_.begin(); }
|
||||
IfcGeom::ConversionResults::const_iterator end() const { return shapes_.end(); }
|
||||
const IfcGeom::ConversionResults& shapes() const { return shapes_; }
|
||||
IfcGeom::ConversionResultShape* as_compound(bool force_meters = false) const;
|
||||
virtual ~brep() {}
|
||||
ifcopenshell::geom::conversion_results::const_iterator begin() const { return shapes_.begin(); }
|
||||
ifcopenshell::geom::conversion_results::const_iterator end() const { return shapes_.end(); }
|
||||
const ifcopenshell::geom::conversion_results& shapes() const { return shapes_; }
|
||||
ifcopenshell::geom::conversion_result_shape* as_compound(bool force_meters = false) const;
|
||||
|
||||
bool calculate_volume(double&) const;
|
||||
bool calculate_surface_area(double&) const;
|
||||
bool calculate_projected_surface_area(const ifcopenshell::geometry::taxonomy::matrix4::ptr& ax, double& along_x, double& along_y, double& along_z) const;
|
||||
bool calculate_projected_surface_area(const ifcopenshell::geom::taxonomy::matrix4::ptr& ax, double& along_x, double& along_y, double& along_z) const;
|
||||
|
||||
int size() const { return (int) shapes_.size(); }
|
||||
const IfcGeom::ConversionResultShape* item(int i) const;
|
||||
const ifcopenshell::geom::conversion_result_shape* item(int i) const;
|
||||
int item_id(int i) const;
|
||||
};
|
||||
|
||||
class IFC_GEOM_API Serialization : public Representation {
|
||||
class IFC_GEOM_API serialization : public representation {
|
||||
private:
|
||||
std::string brep_data_;
|
||||
std::vector<double> surface_styles_;
|
||||
@@ -88,20 +88,20 @@ namespace IfcGeom {
|
||||
const std::string& brep_data() const { return brep_data_; }
|
||||
const std::vector<double>& surface_styles() const { return surface_styles_; }
|
||||
const std::vector<int>& surface_style_ids() const { return surface_style_ids_; }
|
||||
Serialization(const BRep& brep);
|
||||
virtual ~Serialization() {}
|
||||
serialization(const brep& brep);
|
||||
virtual ~serialization() {}
|
||||
private:
|
||||
Serialization();
|
||||
Serialization(const Serialization&);
|
||||
Serialization& operator=(const Serialization&);
|
||||
serialization();
|
||||
serialization(const serialization&);
|
||||
serialization& operator=(const serialization&);
|
||||
};
|
||||
|
||||
class Triangulation : public Representation {
|
||||
class triangulation : public representation {
|
||||
private:
|
||||
// A tuple of <item, material, x, y, z> to store as a key in a map.
|
||||
typedef typename std::tuple<int, int, double, double, double> VertexKey;
|
||||
typedef std::map<VertexKey, int> VertexKeyMap;
|
||||
typedef std::pair<int, int> Edge;
|
||||
typedef typename std::tuple<int, int, double, double, double> vertex_key;
|
||||
typedef std::map<vertex_key, int> vertex_key_map;
|
||||
typedef std::pair<int, int> edge;
|
||||
|
||||
std::vector<double> verts_;
|
||||
|
||||
@@ -115,14 +115,14 @@ namespace IfcGeom {
|
||||
std::vector<double> normals_;
|
||||
std::vector<double> uvs_;
|
||||
std::vector<int> material_ids_;
|
||||
std::vector<ifcopenshell::geometry::taxonomy::style::ptr> materials_;
|
||||
std::vector<ifcopenshell::geom::taxonomy::style::ptr> materials_;
|
||||
std::vector<int> item_ids_;
|
||||
std::vector<int> edges_item_ids_;
|
||||
size_t weld_offset_;
|
||||
VertexKeyMap welds;
|
||||
vertex_key_map welds;
|
||||
|
||||
Triangulation(const ifcopenshell::geometry::Settings& settings, const std::string& entity, const std::string& id)
|
||||
: Representation(settings, entity, id)
|
||||
triangulation(const ifcopenshell::geom::settings& settings, const std::string& entity, const std::string& id)
|
||||
: representation(settings, entity, id)
|
||||
, weld_offset_(0)
|
||||
{}
|
||||
|
||||
@@ -136,14 +136,14 @@ namespace IfcGeom {
|
||||
const std::vector<double>& uvs() const { return uvs_; }
|
||||
std::vector<double>& uvs_ref() { return uvs_; }
|
||||
const std::vector<int>& material_ids() const { return material_ids_; }
|
||||
const std::vector<ifcopenshell::geometry::taxonomy::style::ptr>& materials() const { return materials_; }
|
||||
const std::vector<ifcopenshell::geom::taxonomy::style::ptr>& materials() const { return materials_; }
|
||||
const std::vector<int>& item_ids() const { return item_ids_; }
|
||||
const std::vector<int>& edges_item_ids() const { return edges_item_ids_; }
|
||||
|
||||
Triangulation(const BRep& shape_model);
|
||||
triangulation(const brep& shape_model);
|
||||
|
||||
Triangulation(
|
||||
const ifcopenshell::geometry::Settings& settings,
|
||||
triangulation(
|
||||
const ifcopenshell::geom::settings& settings,
|
||||
const std::string& entity,
|
||||
const std::string& id,
|
||||
const std::vector<double>& verts,
|
||||
@@ -152,11 +152,11 @@ namespace IfcGeom {
|
||||
const std::vector<double>& normals,
|
||||
const std::vector<double>& uvs,
|
||||
const std::vector<int>& material_ids,
|
||||
const std::vector<ifcopenshell::geometry::taxonomy::style::ptr>& materials,
|
||||
const std::vector<ifcopenshell::geom::taxonomy::style::ptr>& materials,
|
||||
const std::vector<int>& item_ids
|
||||
, const std::vector<int>& edges_item_ids
|
||||
)
|
||||
: Representation(settings, entity, id)
|
||||
: representation(settings, entity, id)
|
||||
, verts_(verts)
|
||||
, faces_(faces)
|
||||
, edges_(edges)
|
||||
@@ -168,13 +168,13 @@ namespace IfcGeom {
|
||||
, edges_item_ids_(edges_item_ids)
|
||||
{}
|
||||
|
||||
virtual ~Triangulation() {}
|
||||
virtual ~triangulation() {}
|
||||
|
||||
/// Generates UVs for a single mesh using box projection.
|
||||
/// @todo Very simple impl. Assumes that input vertices and normals match 1:1.
|
||||
static std::vector<double> box_project_uvs(const std::vector<double> &vertices, const std::vector<double> &normals);
|
||||
|
||||
static Triangulation* empty(const ifcopenshell::geometry::Settings& settings) { return new Triangulation(settings, "", ""); }
|
||||
static triangulation* empty(const ifcopenshell::geom::settings& settings) { return new triangulation(settings, "", ""); }
|
||||
|
||||
/// Welds vertices that belong to different faces
|
||||
int addVertex(int item_index, int material_index, double X, double Y, double Z);
|
||||
@@ -230,9 +230,9 @@ namespace IfcGeom {
|
||||
}
|
||||
|
||||
private:
|
||||
Triangulation();
|
||||
Triangulation(const Triangulation&);
|
||||
Triangulation& operator=(const Triangulation&);
|
||||
triangulation();
|
||||
triangulation(const triangulation&);
|
||||
triangulation& operator=(const triangulation&);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+89
-90
@@ -15,7 +15,7 @@
|
||||
* - For non-concurrent iterators, a false return may occur if initialization of the first
|
||||
* element fails, even if subsequent elements could be initialized successfully.
|
||||
*/
|
||||
bool IfcGeom::Iterator::initialize() {
|
||||
bool ifcopenshell::geom::iterator::initialize() {
|
||||
using std::chrono::high_resolution_clock;
|
||||
|
||||
if (initialization_outcome_) {
|
||||
@@ -23,7 +23,7 @@ bool IfcGeom::Iterator::initialize() {
|
||||
}
|
||||
|
||||
time_points[0] = high_resolution_clock::now();
|
||||
std::vector<ifcopenshell::geometry::geometry_conversion_task> reps;
|
||||
std::vector<ifcopenshell::geom::geometry_conversion_task> reps;
|
||||
if (num_threads_ != 1) {
|
||||
// @todo this shouldn't be necessary with properly immutable taxonomy items
|
||||
converter_->mapping()->use_caching() = false;
|
||||
@@ -38,7 +38,7 @@ bool IfcGeom::Iterator::initialize() {
|
||||
for (auto& task : reps) {
|
||||
geometry_conversion_result res;
|
||||
res.index = task.index;
|
||||
if (!settings_.get<ifcopenshell::geometry::settings::NoParallelMapping>().get()) {
|
||||
if (!settings_.get<ifcopenshell::geom::settings::NoParallelMapping>().get()) {
|
||||
res.representation = task.representation;
|
||||
res.products_2 = task.products;
|
||||
} else {
|
||||
@@ -46,25 +46,25 @@ bool IfcGeom::Iterator::initialize() {
|
||||
if (!res.item) {
|
||||
continue;
|
||||
}
|
||||
std::transform(task.products.begin(), task.products.end(), std::back_inserter(res.products), [this, &res](const express::Base& prod) {
|
||||
std::transform(task.products.begin(), task.products.end(), std::back_inserter(res.products), [this, &res](const express::base& prod) {
|
||||
auto prod_item = converter_->mapping()->map(prod);
|
||||
return std::make_pair(prod, ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::geom_item>(prod_item)->matrix);
|
||||
return std::make_pair(prod, ifcopenshell::geom::taxonomy::cast<ifcopenshell::geom::taxonomy::geom_item>(prod_item)->matrix);
|
||||
});
|
||||
}
|
||||
tasks_.push_back(res);
|
||||
}
|
||||
|
||||
if (settings_.get<ifcopenshell::geometry::settings::NoParallelMapping>().get() && settings_.get<ifcopenshell::geometry::settings::PermissiveShapeReuse>().get()) {
|
||||
if (settings_.get<ifcopenshell::geom::settings::NoParallelMapping>().get() && settings_.get<ifcopenshell::geom::settings::PermissiveShapeReuse>().get()) {
|
||||
std::unordered_map<
|
||||
ifcopenshell::geometry::taxonomy::item::ptr,
|
||||
std::vector<std::pair<express::Base, ifcopenshell::geometry::taxonomy::matrix4::ptr>>> folded;
|
||||
ifcopenshell::geom::taxonomy::item::ptr,
|
||||
std::vector<std::pair<express::base, ifcopenshell::geom::taxonomy::matrix4::ptr>>> folded;
|
||||
|
||||
for (auto& r : tasks_) {
|
||||
auto i = r.item;
|
||||
|
||||
Eigen::Matrix4d m4 = Eigen::Matrix4d::Identity();
|
||||
|
||||
while (auto col = std::dynamic_pointer_cast<ifcopenshell::geometry::taxonomy::collection>(i)) {
|
||||
while (auto col = std::dynamic_pointer_cast<ifcopenshell::geom::taxonomy::collection>(i)) {
|
||||
if (col->children.size() == 1) {
|
||||
if (col->matrix) {
|
||||
m4 *= col->matrix->ccomponents();
|
||||
@@ -76,7 +76,7 @@ bool IfcGeom::Iterator::initialize() {
|
||||
}
|
||||
|
||||
for (auto& p : r.products) {
|
||||
auto pl = ifcopenshell::geometry::taxonomy::matrix4::ptr(p.second->clone_());
|
||||
auto pl = ifcopenshell::geom::taxonomy::matrix4::ptr(p.second->clone_());
|
||||
pl->components() *= m4;
|
||||
folded[i].push_back(
|
||||
{ p.first, pl }
|
||||
@@ -98,13 +98,13 @@ bool IfcGeom::Iterator::initialize() {
|
||||
}
|
||||
}
|
||||
|
||||
if (settings_.get<ifcopenshell::geometry::settings::NoParallelMapping>().get()) {
|
||||
if (settings_.get<ifcopenshell::geom::settings::NoParallelMapping>().get()) {
|
||||
remove_offset_();
|
||||
}
|
||||
|
||||
size_t num_products = 0;
|
||||
for (auto& r : tasks_) {
|
||||
num_products += !settings_.get<ifcopenshell::geometry::settings::NoParallelMapping>().get() ? r.products_2.size() : r.products.size();
|
||||
num_products += !settings_.get<ifcopenshell::geom::settings::NoParallelMapping>().get() ? r.products_2.size() : r.products.size();
|
||||
}
|
||||
|
||||
time_points[2] = high_resolution_clock::now();
|
||||
@@ -116,7 +116,7 @@ bool IfcGeom::Iterator::initialize() {
|
||||
|
||||
std::vector<taxonomy::ptr> items;
|
||||
std::map<taxonomy::ptr, taxonomy::matrix4> placements;
|
||||
std::transform(products.begin(), products.end(), std::back_inserter(items), [this, &placements](express::Base p) {
|
||||
std::transform(products.begin(), products.end(), std::back_inserter(items), [this, &placements](express::base p) {
|
||||
auto item = converter_->mapping()->map(p);
|
||||
// Product placements do not affect item reuse and should temporarily be swapped to identity
|
||||
if (item) {
|
||||
@@ -132,7 +132,7 @@ bool IfcGeom::Iterator::initialize() {
|
||||
geometry_conversion_result r;
|
||||
r.item = *it;
|
||||
std::transform(it, jt, std::back_inserter(r.products), [&r, &placements](taxonomy::ptr product_node) {
|
||||
return std::make_pair((express::Base) product_node->instance, placements[product_node]);
|
||||
return std::make_pair((express::base) product_node->instance, placements[product_node]);
|
||||
});
|
||||
tasks_.push_back(r);
|
||||
it = jt;
|
||||
@@ -144,7 +144,7 @@ bool IfcGeom::Iterator::initialize() {
|
||||
if (tasks_.size() == 0) {
|
||||
logger_.warning("GEO", 51, "No representations encountered, aborting");
|
||||
initialization_outcome_ = false;
|
||||
} else if (!settings_.get<ifcopenshell::geometry::settings::DeferProcessingFirstElement>().get()) {
|
||||
} else if (!settings_.get<ifcopenshell::geom::settings::DeferProcessingFirstElement>().get()) {
|
||||
|
||||
task_iterator_ = tasks_.begin();
|
||||
|
||||
@@ -167,13 +167,13 @@ bool IfcGeom::Iterator::initialize() {
|
||||
return *initialization_outcome_;
|
||||
}
|
||||
|
||||
void IfcGeom::Iterator::flush_worker_log(ifcopenshell::geometry::Converter* kernel) {
|
||||
void ifcopenshell::geom::iterator::flush_worker_log(ifcopenshell::geom::converter* kernel) {
|
||||
if (kernel && &kernel->logger() != &logger_) {
|
||||
logger_.append(kernel->logger());
|
||||
}
|
||||
}
|
||||
|
||||
void IfcGeom::Iterator::process_finished_rep(geometry_conversion_result* rep, ifcopenshell::geometry::Converter* kernel) {
|
||||
void ifcopenshell::geom::iterator::process_finished_rep(geometry_conversion_result* rep, ifcopenshell::geom::converter* kernel) {
|
||||
flush_worker_log(kernel);
|
||||
|
||||
if (rep->elements.empty()) {
|
||||
@@ -194,7 +194,7 @@ void IfcGeom::Iterator::process_finished_rep(geometry_conversion_result* rep, if
|
||||
progress_ = (int)(++processed_ * 100 / tasks_.size());
|
||||
}
|
||||
|
||||
void IfcGeom::Iterator::process_concurrently() {
|
||||
void ifcopenshell::geom::iterator::process_concurrently() {
|
||||
size_t conc_threads = num_threads_;
|
||||
if (conc_threads > tasks_.size()) {
|
||||
conc_threads = tasks_.size();
|
||||
@@ -211,13 +211,13 @@ void IfcGeom::Iterator::process_concurrently() {
|
||||
if (worker_logger.output_format() != ::logger::FMT_INMEMORY) {
|
||||
worker_logger.set_output(static_cast<std::ostream*>(nullptr), static_cast<std::ostream*>(nullptr));
|
||||
}
|
||||
kernel_pool.push_back(new ifcopenshell::geometry::Converter(std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel>(converter_->kernel()->clone(worker_logger)), ifc_file, settings_, worker_logger));
|
||||
kernel_pool.push_back(new ifcopenshell::geom::converter(std::unique_ptr<ifcopenshell::geom::kernels::abstract_kernel>(converter_->kernel()->clone(worker_logger)), ifc_file, settings_, worker_logger));
|
||||
}
|
||||
|
||||
std::vector<std::future<geometry_conversion_result*>> threadpool;
|
||||
|
||||
for (auto& rep : tasks_) {
|
||||
ifcopenshell::geometry::Converter* K = nullptr;
|
||||
ifcopenshell::geom::converter* K = nullptr;
|
||||
if (threadpool.size() < kernel_pool.size()) {
|
||||
K = kernel_pool[threadpool.size()];
|
||||
}
|
||||
@@ -242,8 +242,8 @@ void IfcGeom::Iterator::process_concurrently() {
|
||||
|
||||
std::future<geometry_conversion_result*> fu = std::async(
|
||||
std::launch::async, [this](
|
||||
ifcopenshell::geometry::Converter* kernel,
|
||||
ifcopenshell::geometry::Settings settings,
|
||||
ifcopenshell::geom::converter* kernel,
|
||||
ifcopenshell::geom::settings settings,
|
||||
geometry_conversion_result* rep) {
|
||||
// Catch exceptions to be safe from freezing the iterator.
|
||||
try {
|
||||
@@ -281,7 +281,7 @@ void IfcGeom::Iterator::process_concurrently() {
|
||||
|
||||
finished_ = true;
|
||||
|
||||
logger_.set_product(std::optional<express::Base>{});
|
||||
logger_.set_product(std::optional<express::base>{});
|
||||
|
||||
if (!terminating_) {
|
||||
logger_.status("\rDone creating geometry (" + boost::lexical_cast<std::string>(all_processed_elements_.size()) +
|
||||
@@ -291,7 +291,7 @@ void IfcGeom::Iterator::process_concurrently() {
|
||||
|
||||
/// Computes model's bounding box (bounds_min and bounds_max).
|
||||
/// @note Can take several minutes for large files.
|
||||
void IfcGeom::Iterator::compute_bounds(bool with_geometry)
|
||||
void ifcopenshell::geom::iterator::compute_bounds(bool with_geometry)
|
||||
{
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
bounds_min_.components()(i) = std::numeric_limits<double>::infinity();
|
||||
@@ -301,9 +301,9 @@ void IfcGeom::Iterator::compute_bounds(bool with_geometry)
|
||||
if (with_geometry) {
|
||||
size_t num_created = 0;
|
||||
do {
|
||||
IfcGeom::Element* geom_object = get();
|
||||
const IfcGeom::TriangulationElement* o = static_cast<const IfcGeom::TriangulationElement*>(geom_object);
|
||||
const IfcGeom::Representation::Triangulation& mesh = o->geometry();
|
||||
ifcopenshell::geom::element* geom_object = get();
|
||||
const ifcopenshell::geom::triangulation_element* o = static_cast<const ifcopenshell::geom::triangulation_element*>(geom_object);
|
||||
const ifcopenshell::geom::Representation::triangulation& mesh = o->geometry();
|
||||
auto mat = o->transformation().data()->ccomponents();
|
||||
Eigen::Vector4d vec, transformed;
|
||||
|
||||
@@ -321,17 +321,17 @@ void IfcGeom::Iterator::compute_bounds(bool with_geometry)
|
||||
}
|
||||
} while (++num_created, next());
|
||||
} else {
|
||||
std::vector<ifcopenshell::geometry::geometry_conversion_task> reps;
|
||||
std::vector<ifcopenshell::geom::geometry_conversion_task> reps;
|
||||
converter_->mapping()->get_representations(reps, filters_);
|
||||
|
||||
std::vector<express::Base> products;
|
||||
std::vector<express::base> products;
|
||||
for (auto& r : reps) {
|
||||
std::copy(r.products.begin(), r.products.end(), std::back_inserter(products));
|
||||
}
|
||||
|
||||
for (auto& product : products) {
|
||||
auto prod_item = converter_->mapping()->map(product);
|
||||
auto vec = ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::geom_item>(prod_item)->matrix->translation_part();
|
||||
auto vec = ifcopenshell::geom::taxonomy::cast<ifcopenshell::geom::taxonomy::geom_item>(prod_item)->matrix->translation_part();
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
bounds_min_.components()(i) = std::min(bounds_min_.components()(i), vec(i));
|
||||
@@ -341,7 +341,7 @@ void IfcGeom::Iterator::compute_bounds(bool with_geometry)
|
||||
}
|
||||
}
|
||||
|
||||
express::Base IfcGeom::Iterator::create_shape_model_for_next_entity() {
|
||||
express::base ifcopenshell::geom::iterator::create_shape_model_for_next_entity() {
|
||||
geometry_conversion_result* task = nullptr;
|
||||
for (; task_iterator_ < tasks_.end();) {
|
||||
task = &*task_iterator_++;
|
||||
@@ -356,44 +356,44 @@ express::Base IfcGeom::Iterator::create_shape_model_for_next_entity() {
|
||||
process_finished_rep(task);
|
||||
return task->item->instance;
|
||||
} else {
|
||||
return express::Base{};
|
||||
return express::base{};
|
||||
}
|
||||
}
|
||||
|
||||
void IfcGeom::Iterator::create_element_(ifcopenshell::geometry::Converter* kernel, ifcopenshell::geometry::Settings settings, geometry_conversion_result* rep)
|
||||
void ifcopenshell::geom::iterator::create_element_(ifcopenshell::geom::converter* kernel, ifcopenshell::geom::settings settings, geometry_conversion_result* rep)
|
||||
{
|
||||
::logger& kernel_logger = kernel->logger();
|
||||
|
||||
if (!settings_.get<ifcopenshell::geometry::settings::NoParallelMapping>().get()) {
|
||||
if (!settings_.get<ifcopenshell::geom::settings::NoParallelMapping>().get()) {
|
||||
rep->item = kernel->mapping()->map(rep->representation);
|
||||
if (!rep->item) {
|
||||
return;
|
||||
}
|
||||
std::transform(rep->products_2.begin(), rep->products_2.end(), std::back_inserter(rep->products), [this, &rep, kernel](const express::Base& prod) {
|
||||
std::transform(rep->products_2.begin(), rep->products_2.end(), std::back_inserter(rep->products), [this, &rep, kernel](const express::base& prod) {
|
||||
auto prod_item = kernel->mapping()->map(prod);
|
||||
return std::make_pair(prod, ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::geom_item>(prod_item)->matrix);
|
||||
return std::make_pair(prod, ifcopenshell::geom::taxonomy::cast<ifcopenshell::geom::taxonomy::geom_item>(prod_item)->matrix);
|
||||
});
|
||||
} else {
|
||||
}
|
||||
|
||||
auto product_node = rep->products.front();
|
||||
const express::Base product = product_node.first;
|
||||
const express::base product = product_node.first;
|
||||
const auto& place = product_node.second;
|
||||
|
||||
kernel_logger.set_product(product);
|
||||
|
||||
IfcGeom::BRepElement* brep = static_cast<IfcGeom::BRepElement*>(create_processed_element_([kernel, settings, product, place, rep]() {
|
||||
ifcopenshell::geom::brep_element* brep = static_cast<ifcopenshell::geom::brep_element*>(create_processed_element_([kernel, settings, product, place, rep]() {
|
||||
return kernel->create_brep_for_representation_and_product(rep->item, product, place);
|
||||
}));
|
||||
|
||||
if (!brep) {
|
||||
kernel_logger.set_product(std::optional<express::Base>{});
|
||||
kernel_logger.set_product(std::optional<express::base>{});
|
||||
return;
|
||||
}
|
||||
|
||||
auto elem = process_based_on_settings(settings, brep, kernel_logger);
|
||||
if (!elem) {
|
||||
kernel_logger.set_product(std::optional<express::Base>{});
|
||||
kernel_logger.set_product(std::optional<express::base>{});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -402,16 +402,16 @@ void IfcGeom::Iterator::create_element_(ifcopenshell::geometry::Converter* kerne
|
||||
|
||||
for (auto it = rep->products.begin() + 1; it != rep->products.end(); ++it) {
|
||||
const auto& p = *it;
|
||||
const express::Base product2 = p.first;
|
||||
const express::base product2 = p.first;
|
||||
const auto& place2 = p.second;
|
||||
|
||||
kernel_logger.set_product(product2);
|
||||
|
||||
IfcGeom::BRepElement* brep2 = static_cast<IfcGeom::BRepElement*>(create_processed_element_([kernel, settings, product2, place2, brep]() {
|
||||
ifcopenshell::geom::brep_element* brep2 = static_cast<ifcopenshell::geom::brep_element*>(create_processed_element_([kernel, settings, product2, place2, brep]() {
|
||||
return kernel->create_brep_for_processed_representation(product2, place2, brep);
|
||||
}));
|
||||
if (brep2) {
|
||||
auto elem2 = process_based_on_settings(settings, brep2, kernel_logger, dynamic_cast<IfcGeom::TriangulationElement*>(elem));
|
||||
auto elem2 = process_based_on_settings(settings, brep2, kernel_logger, dynamic_cast<ifcopenshell::geom::triangulation_element*>(elem));
|
||||
if (elem2) {
|
||||
rep->breps.push_back(brep2);
|
||||
rep->elements.push_back(elem2);
|
||||
@@ -419,37 +419,37 @@ void IfcGeom::Iterator::create_element_(ifcopenshell::geometry::Converter* kerne
|
||||
}
|
||||
}
|
||||
|
||||
kernel_logger.set_product(std::optional<express::Base>{});
|
||||
kernel_logger.set_product(std::optional<express::base>{});
|
||||
}
|
||||
|
||||
IfcGeom::Element* IfcGeom::Iterator::process_based_on_settings(ifcopenshell::geometry::Settings settings, IfcGeom::BRepElement* elem, ::logger& logger, IfcGeom::TriangulationElement* previous)
|
||||
ifcopenshell::geom::element* ifcopenshell::geom::iterator::process_based_on_settings(ifcopenshell::geom::settings settings, ifcopenshell::geom::brep_element* elem, ::logger& logger, ifcopenshell::geom::triangulation_element* previous)
|
||||
{
|
||||
if (settings.get<ifcopenshell::geometry::settings::IteratorOutput>().get() == ifcopenshell::geometry::settings::SERIALIZED) {
|
||||
if (settings.get<ifcopenshell::geom::settings::IteratorOutput>().get() == ifcopenshell::geom::settings::SERIALIZED) {
|
||||
try {
|
||||
return new IfcGeom::SerializedElement(*elem);
|
||||
return new ifcopenshell::geom::serialized_element(*elem);
|
||||
} catch (...) {
|
||||
logger.message(::logger::LOG_ERROR, "GEO", 54, "Getting a serialized element from model failed.");
|
||||
return nullptr;
|
||||
}
|
||||
} else if (settings.get<ifcopenshell::geometry::settings::IteratorOutput>().get() == ifcopenshell::geometry::settings::TRIANGULATED) {
|
||||
} else if (settings.get<ifcopenshell::geom::settings::IteratorOutput>().get() == ifcopenshell::geom::settings::TRIANGULATED) {
|
||||
return create_processed_element_([elem, previous, &logger]() {
|
||||
try {
|
||||
if (!previous) {
|
||||
return new TriangulationElement(*elem);
|
||||
return new triangulation_element(*elem);
|
||||
} else {
|
||||
return new TriangulationElement(*elem, previous->geometry_pointer());
|
||||
return new triangulation_element(*elem, previous->geometry_pointer());
|
||||
}
|
||||
} catch (...) {
|
||||
logger.message(::logger::LOG_ERROR, "GEO", 55, "Getting a triangulation element from model failed.");
|
||||
}
|
||||
return (TriangulationElement*)nullptr;
|
||||
return (triangulation_element*)nullptr;
|
||||
});
|
||||
} else {
|
||||
return elem;
|
||||
}
|
||||
}
|
||||
|
||||
bool IfcGeom::Iterator::wait_for_element() {
|
||||
bool ifcopenshell::geom::iterator::wait_for_element() {
|
||||
while (true) {
|
||||
size_t s;
|
||||
{
|
||||
@@ -467,7 +467,7 @@ bool IfcGeom::Iterator::wait_for_element() {
|
||||
}
|
||||
}
|
||||
|
||||
void IfcGeom::Iterator::log_timepoints() const {
|
||||
void ifcopenshell::geom::iterator::log_timepoints() const {
|
||||
using std::chrono::high_resolution_clock;
|
||||
using std::chrono::duration;
|
||||
using namespace std::string_literals;
|
||||
@@ -485,9 +485,9 @@ void IfcGeom::Iterator::log_timepoints() const {
|
||||
}
|
||||
}
|
||||
|
||||
void IfcGeom::Iterator::validate_iterator_state() const {
|
||||
void ifcopenshell::geom::iterator::validate_iterator_state() const {
|
||||
if (!initialization_outcome_) {
|
||||
throw std::runtime_error("Iterator not initialized");
|
||||
throw std::runtime_error("iterator not initialized");
|
||||
}
|
||||
|
||||
// Causes:
|
||||
@@ -499,13 +499,13 @@ void IfcGeom::Iterator::validate_iterator_state() const {
|
||||
}
|
||||
|
||||
if (task_result_ptr_exhausted) {
|
||||
throw std::runtime_error("Iterator is exhausted");
|
||||
throw std::runtime_error("iterator is exhausted");
|
||||
}
|
||||
}
|
||||
|
||||
/// Moves to the next shape representation, create its geometry, and returns the associated product.
|
||||
/// Use get() to retrieve the created geometry.
|
||||
express::Base IfcGeom::Iterator::next() {
|
||||
express::base ifcopenshell::geom::iterator::next() {
|
||||
using std::chrono::high_resolution_clock;
|
||||
validate_iterator_state();
|
||||
|
||||
@@ -516,11 +516,11 @@ express::Base IfcGeom::Iterator::next() {
|
||||
|
||||
if (num_threads_ != 1) {
|
||||
if (!wait_for_element()) {
|
||||
logger_.set_product(std::optional<express::Base>{});
|
||||
logger_.set_product(std::optional<express::base>{});
|
||||
time_points[3] = high_resolution_clock::now();
|
||||
log_timepoints();
|
||||
task_result_ptr_exhausted = true;
|
||||
return express::Base{};
|
||||
return express::base{};
|
||||
}
|
||||
|
||||
task_result_iterator_++;
|
||||
@@ -532,11 +532,11 @@ express::Base IfcGeom::Iterator::next() {
|
||||
// shape representation
|
||||
if (task_result_iterator_ == --all_processed_elements_.end()) {
|
||||
if (!create()) {
|
||||
logger_.set_product(std::optional<express::Base>{});
|
||||
logger_.set_product(std::optional<express::base>{});
|
||||
time_points[3] = high_resolution_clock::now();
|
||||
log_timepoints();
|
||||
task_result_ptr_exhausted = true;
|
||||
return express::Base{};
|
||||
return express::base{};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -548,21 +548,21 @@ express::Base IfcGeom::Iterator::next() {
|
||||
}
|
||||
|
||||
/// Gets the representation of the current geometrical entity.
|
||||
IfcGeom::Element* IfcGeom::Iterator::get()
|
||||
ifcopenshell::geom::element* ifcopenshell::geom::iterator::get()
|
||||
{
|
||||
validate_iterator_state();
|
||||
|
||||
auto ret = *task_result_iterator_;
|
||||
|
||||
// If we want to organize the element considering their hierarchy
|
||||
if (settings_.get<ifcopenshell::geometry::settings::UseElementHierarchy>().get()) {
|
||||
if (settings_.get<ifcopenshell::geom::settings::UseElementHierarchy>().get()) {
|
||||
// We are going to build a vector with the element parents.
|
||||
// First, create the parent vector
|
||||
std::vector<const IfcGeom::Element*> parents;
|
||||
std::vector<const ifcopenshell::geom::element*> parents;
|
||||
|
||||
// if the element has a parent
|
||||
if (ret->parent_id() != -1) {
|
||||
const IfcGeom::Element* parent_object = NULL;
|
||||
const ifcopenshell::geom::element* parent_object = NULL;
|
||||
bool hasParent = true;
|
||||
|
||||
// get the parent
|
||||
@@ -598,7 +598,7 @@ IfcGeom::Element* IfcGeom::Iterator::get()
|
||||
hasParent = hasParent && parent_object->parent_id() != -1;
|
||||
}
|
||||
|
||||
// when done push the parent list in the Element object
|
||||
// when done push the parent list in the element object
|
||||
ret->SetParents(parents);
|
||||
}
|
||||
}
|
||||
@@ -606,19 +606,19 @@ IfcGeom::Element* IfcGeom::Iterator::get()
|
||||
return ret;
|
||||
}
|
||||
|
||||
const IfcGeom::Element* IfcGeom::Iterator::get_object(int id) {
|
||||
ifcopenshell::geometry::taxonomy::matrix4::ptr m4;
|
||||
const ifcopenshell::geom::element* ifcopenshell::geom::iterator::get_object(int id) {
|
||||
ifcopenshell::geom::taxonomy::matrix4::ptr m4;
|
||||
int parent_id = -1;
|
||||
std::string instance_type, product_name, product_guid;
|
||||
express::Base ifc_product;
|
||||
express::base ifc_product;
|
||||
|
||||
try {
|
||||
ifc_product = ifc_file->instance_by_id(id);
|
||||
instance_type = ifc_product.declaration().name();
|
||||
|
||||
if (ifc_product.declaration().is("IfcRoot")) {
|
||||
product_guid = ifc_product.as<express::Entity>().get_value<std::string>("GlobalId");
|
||||
product_name = ifc_product.as<express::Entity>().get_value<std::string>("Name", "");
|
||||
product_guid = ifc_product.as<express::entity>().get_value<std::string>("GlobalId");
|
||||
product_name = ifc_product.as<express::entity>().get_value<std::string>("Name", "");
|
||||
}
|
||||
|
||||
auto parent_object = converter_->mapping()->get_decomposing_entity(ifc_product);
|
||||
@@ -628,7 +628,7 @@ const IfcGeom::Element* IfcGeom::Iterator::get_object(int id) {
|
||||
|
||||
// fails in case of IfcProject
|
||||
auto mapped = converter_->mapping()->map(ifc_product);
|
||||
auto casted = mapped ? ifcopenshell::geometry::taxonomy::dcast<ifcopenshell::geometry::taxonomy::geom_item>(mapped) : nullptr;
|
||||
auto casted = mapped ? ifcopenshell::geom::taxonomy::dcast<ifcopenshell::geom::taxonomy::geom_item>(mapped) : nullptr;
|
||||
|
||||
if (casted) {
|
||||
m4 = casted->matrix;
|
||||
@@ -639,12 +639,12 @@ const IfcGeom::Element* IfcGeom::Iterator::get_object(int id) {
|
||||
logger_.error("GEO", 59, "Unknown error returning product");
|
||||
}
|
||||
|
||||
Element* ifc_object = new Element(settings_, id, parent_id, product_name, instance_type, product_guid, "", m4, ifc_product.as<express::Entity>());
|
||||
element* ifc_object = new element(settings_, id, parent_id, product_name, instance_type, product_guid, "", m4, ifc_product.as<express::entity>());
|
||||
return ifc_object;
|
||||
}
|
||||
|
||||
express::Base IfcGeom::Iterator::create() {
|
||||
express::Base product;
|
||||
express::base ifcopenshell::geom::iterator::create() {
|
||||
express::base product;
|
||||
try {
|
||||
product = create_shape_model_for_next_entity();
|
||||
} catch (const std::exception& e) {
|
||||
@@ -657,20 +657,19 @@ express::Base IfcGeom::Iterator::create() {
|
||||
return product;
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::taxonomy::direction3::ptr IfcGeom::Iterator::remove_offset_() {
|
||||
ifcopenshell::geom::taxonomy::direction3::ptr ifcopenshell::geom::iterator::remove_offset_() {
|
||||
|
||||
using namespace ifcopenshell::geometry::taxonomy;
|
||||
using namespace ifcopenshell::geometry::settings;
|
||||
using namespace ifcopenshell::geom::taxonomy;
|
||||
|
||||
if (!settings_.get<MaxOffset>().has()) {
|
||||
if (!settings_.get<ifcopenshell::geom::settings::MaxOffset>().has()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!settings_.get<NoParallelMapping>().get()) {
|
||||
if (!settings_.get<ifcopenshell::geom::settings::NoParallelMapping>().get()) {
|
||||
throw std::runtime_error("remove_offset() can only be called with defer-processing-first-element and no-parallel-mapping settings");
|
||||
}
|
||||
|
||||
auto collect_offset = [&](const item::ptr& itm, const std::vector<std::pair<express::Base, matrix4::ptr>>& pr) -> std::pair<double, Eigen::Vector3d> {
|
||||
auto collect_offset = [&](const item::ptr& itm, const std::vector<std::pair<express::base, matrix4::ptr>>& pr) -> std::pair<double, Eigen::Vector3d> {
|
||||
std::function<std::pair<double, Eigen::Vector3d>(const item::ptr&, Eigen::Matrix4d)> traverse;
|
||||
traverse = [&](const item::ptr& node, Eigen::Matrix4d m4) -> std::pair<double, Eigen::Vector3d> {
|
||||
if (auto shl = std::dynamic_pointer_cast<shell>(node)) {
|
||||
@@ -679,7 +678,7 @@ ifcopenshell::geometry::taxonomy::direction3::ptr IfcGeom::Iterator::remove_offs
|
||||
v << p->components()(0), p->components()(1), p->components()(2), 1.0;
|
||||
Eigen::Vector3d translation_part = (m4 * v).head<3>();
|
||||
double translation_amnt = translation_part.norm();
|
||||
if (translation_amnt > settings_.get<MaxOffset>().get()) {
|
||||
if (translation_amnt > settings_.get<ifcopenshell::geom::settings::MaxOffset>().get()) {
|
||||
return { translation_amnt, translation_part };
|
||||
} else {
|
||||
return { 0.0, Eigen::Vector3d::Zero() };
|
||||
@@ -692,7 +691,7 @@ ifcopenshell::geometry::taxonomy::direction3::ptr IfcGeom::Iterator::remove_offs
|
||||
}
|
||||
Eigen::Vector3d translation_part = m4.block<3, 1>(0, 3);
|
||||
double translation_amnt = translation_part.norm();
|
||||
if (translation_amnt > settings_.get<MaxOffset>().get()) {
|
||||
if (translation_amnt > settings_.get<ifcopenshell::geom::settings::MaxOffset>().get()) {
|
||||
return { translation_amnt, translation_part };
|
||||
} else if (auto col = std::dynamic_pointer_cast<collection>(node)) {
|
||||
std::vector<std::pair<double, Eigen::Vector3d>> child_transforms;
|
||||
@@ -717,8 +716,8 @@ ifcopenshell::geometry::taxonomy::direction3::ptr IfcGeom::Iterator::remove_offs
|
||||
|
||||
Eigen::Vector3d vec;
|
||||
|
||||
if (settings_.get<ApplyOffset>().has()) {
|
||||
auto vs = settings_.get<ApplyOffset>().get();
|
||||
if (settings_.get<ifcopenshell::geom::settings::ApplyOffset>().has()) {
|
||||
auto vs = settings_.get<ifcopenshell::geom::settings::ApplyOffset>().get();
|
||||
if (vs.size() != 3) {
|
||||
throw std::runtime_error("ApplyOffset setting must be a vector of size 3");
|
||||
}
|
||||
@@ -750,7 +749,7 @@ ifcopenshell::geometry::taxonomy::direction3::ptr IfcGeom::Iterator::remove_offs
|
||||
Eigen::Matrix4d translation_matrix = Eigen::Matrix4d::Identity();
|
||||
translation_matrix.block<3, 1>(0, 3) = vec;
|
||||
|
||||
auto remove_offset = [&](const item::ptr& itm, const std::vector<std::pair<express::Base, matrix4::ptr>>& pr) -> bool {
|
||||
auto remove_offset = [&](const item::ptr& itm, const std::vector<std::pair<express::base, matrix4::ptr>>& pr) -> bool {
|
||||
std::function<bool(const item::ptr&, Eigen::Matrix4d)> traverse;
|
||||
traverse = [&](const item::ptr& node, Eigen::Matrix4d m4) -> bool {
|
||||
if (auto shl = std::dynamic_pointer_cast<shell>(node)) {
|
||||
@@ -759,7 +758,7 @@ ifcopenshell::geometry::taxonomy::direction3::ptr IfcGeom::Iterator::remove_offs
|
||||
v << p->components()(0), p->components()(1), p->components()(2), 1.0;
|
||||
Eigen::Vector3d translation_part = (m4 * v).head<3>();
|
||||
double translation_amnt = translation_part.norm();
|
||||
if (translation_amnt > settings_.get<MaxOffset>().get()) {
|
||||
if (translation_amnt > settings_.get<ifcopenshell::geom::settings::MaxOffset>().get()) {
|
||||
shl->matrix = make<matrix4>(translation_matrix);
|
||||
}
|
||||
return true;
|
||||
@@ -771,7 +770,7 @@ ifcopenshell::geometry::taxonomy::direction3::ptr IfcGeom::Iterator::remove_offs
|
||||
}
|
||||
Eigen::Vector3d translation_part = m4b.block<3, 1>(0, 3);
|
||||
double translation_amnt = translation_part.norm();
|
||||
if (translation_amnt > settings_.get<MaxOffset>().get()) {
|
||||
if (translation_amnt > settings_.get<ifcopenshell::geom::settings::MaxOffset>().get()) {
|
||||
auto inverted_rot_scale3 = m4.block<3, 3>(0, 0).inverse();
|
||||
Eigen::Matrix4d inverted_rot_scale = Eigen::Matrix4d::Identity();
|
||||
inverted_rot_scale.block<3, 3>(0, 0) = inverted_rot_scale3;
|
||||
@@ -807,7 +806,7 @@ ifcopenshell::geometry::taxonomy::direction3::ptr IfcGeom::Iterator::remove_offs
|
||||
for (auto& p : task.products) {
|
||||
auto bb = p.second->components().block<3, 1>(0, 3);
|
||||
double translation_amnt = bb.norm();
|
||||
if (translation_amnt > settings_.get<MaxOffset>().get()) {
|
||||
if (translation_amnt > settings_.get<ifcopenshell::geom::settings::MaxOffset>().get()) {
|
||||
// block has an underlying mutable ref to the matrix
|
||||
bb += vec;
|
||||
} else {
|
||||
@@ -829,7 +828,7 @@ ifcopenshell::geometry::taxonomy::direction3::ptr IfcGeom::Iterator::remove_offs
|
||||
return make<direction3>(vec);
|
||||
}
|
||||
|
||||
IfcGeom::Iterator::~Iterator() {
|
||||
ifcopenshell::geom::iterator::~iterator() {
|
||||
if (num_threads_ != 1) {
|
||||
terminating_ = true;
|
||||
|
||||
|
||||
+61
-61
@@ -22,7 +22,7 @@
|
||||
* Geometrical data in an IFC file consists of shapes (IfcShapeRepresentation) *
|
||||
* and instances (SUBTYPE OF IfcBuildingElement e.g. IfcWindow). *
|
||||
* *
|
||||
* IfcGeom::Representation::Triangulation is a class that represents a *
|
||||
* ifcopenshell::geom::Representation::triangulation is a class that represents a *
|
||||
* triangulated IfcShapeRepresentation. *
|
||||
* Triangulation.verts is a 1 dimensional vector of float defining the *
|
||||
* cartesian coordinates of the vertices of the triangulated shape in the *
|
||||
@@ -32,25 +32,25 @@
|
||||
* Triangulation.edges is a 1 dimensional vector of int in {0,1} that dictates*
|
||||
* the visibility of the edges that span the faces in Triangulation.faces *
|
||||
* *
|
||||
* IfcGeom::Element represents the actual IfcBuildingElements. *
|
||||
* ifcopenshell::geom::element represents the actual IfcBuildingElements. *
|
||||
* IfcGeomObject.name is the GUID of the element *
|
||||
* IfcGeomObject.type is the datatype of the element e.g. IfcWindow *
|
||||
* IfcGeomObject.mesh is a pointer to an IfcMesh *
|
||||
* IfcGeomObject.transformation.matrix is a 4x3 matrix that defines the *
|
||||
* orientation and translation of the mesh in relation to the world origin *
|
||||
* *
|
||||
* IfcGeom::Iterator::initialize() *
|
||||
* ifcopenshell::geom::iterator::initialize() *
|
||||
* finds the most suitable representation contexts. Returns true iff *
|
||||
* at least a single representation will process successfully *
|
||||
* *
|
||||
* IfcGeom::Iterator::get() *
|
||||
* returns a pointer to the current IfcGeom::Element *
|
||||
* ifcopenshell::geom::iterator::get() *
|
||||
* returns a pointer to the current ifcopenshell::geom::element *
|
||||
* *
|
||||
* IfcGeom::Iterator::next() *
|
||||
* ifcopenshell::geom::iterator::next() *
|
||||
* returns true iff a following entity is available for a successive call to *
|
||||
* IfcGeom::Iterator::get() *
|
||||
* ifcopenshell::geom::iterator::get() *
|
||||
* *
|
||||
* IfcGeom::Iterator::progress() *
|
||||
* ifcopenshell::geom::iterator::progress() *
|
||||
* returns an int in [0..100] that indicates the overall progress *
|
||||
* *
|
||||
********************************************************************************/
|
||||
@@ -80,21 +80,21 @@
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
|
||||
namespace IfcGeom {
|
||||
namespace ifcopenshell::geom {
|
||||
|
||||
struct IFC_GEOM_API geometry_conversion_result {
|
||||
int index;
|
||||
|
||||
// For NoParallelMapping==true
|
||||
ifcopenshell::geometry::taxonomy::ptr item;
|
||||
std::vector<std::pair<express::Base, ifcopenshell::geometry::taxonomy::matrix4::ptr>> products;
|
||||
ifcopenshell::geom::taxonomy::ptr item;
|
||||
std::vector<std::pair<express::base, ifcopenshell::geom::taxonomy::matrix4::ptr>> products;
|
||||
|
||||
// For NoParallelMapping==false
|
||||
express::Base representation;
|
||||
std::vector<express::Base> products_2;
|
||||
express::base representation;
|
||||
std::vector<express::base> products_2;
|
||||
|
||||
std::vector<IfcGeom::BRepElement*> breps;
|
||||
std::vector<IfcGeom::Element*> elements;
|
||||
std::vector<ifcopenshell::geom::brep_element*> breps;
|
||||
std::vector<ifcopenshell::geom::element*> elements;
|
||||
|
||||
bool is_parallel() const {
|
||||
return !!representation;
|
||||
@@ -102,7 +102,7 @@ namespace IfcGeom {
|
||||
};
|
||||
|
||||
|
||||
class IFC_GEOM_API Iterator {
|
||||
class IFC_GEOM_API iterator {
|
||||
private:
|
||||
std::atomic<bool> finished_{ false };
|
||||
std::atomic<bool> terminating_{ false };
|
||||
@@ -112,35 +112,35 @@ namespace IfcGeom {
|
||||
std::vector<geometry_conversion_result> tasks_;
|
||||
std::vector<geometry_conversion_result>::iterator task_iterator_;
|
||||
|
||||
std::list<IfcGeom::Element*> all_processed_elements_;
|
||||
std::list<IfcGeom::BRepElement*> all_processed_native_elements_;
|
||||
std::list<ifcopenshell::geom::element*> all_processed_elements_;
|
||||
std::list<ifcopenshell::geom::brep_element*> all_processed_native_elements_;
|
||||
|
||||
std::list<IfcGeom::Element*>::const_iterator task_result_iterator_;
|
||||
std::list<IfcGeom::BRepElement*>::const_iterator native_task_result_iterator_;
|
||||
std::list<ifcopenshell::geom::element*>::const_iterator task_result_iterator_;
|
||||
std::list<ifcopenshell::geom::brep_element*>::const_iterator native_task_result_iterator_;
|
||||
|
||||
std::mutex element_ready_mutex_;
|
||||
bool task_result_ptr_initialized = false;
|
||||
bool task_result_ptr_exhausted = false;
|
||||
size_t async_elements_returned_ = 0;
|
||||
|
||||
ifcopenshell::geometry::Settings settings_;
|
||||
ifcopenshell::geom::settings settings_;
|
||||
ifcopenshell::file* ifc_file;
|
||||
std::vector<ifcopenshell::geometry::filter_t> filters_;
|
||||
std::vector<ifcopenshell::geom::filter_t> filters_;
|
||||
int num_threads_;
|
||||
std::string geometry_library_;
|
||||
::logger& logger_;
|
||||
|
||||
// When single-threaded
|
||||
ifcopenshell::geometry::Converter* converter_;
|
||||
ifcopenshell::geom::converter* converter_;
|
||||
|
||||
// When multi-threaded
|
||||
std::vector<ifcopenshell::geometry::Converter*> kernel_pool;
|
||||
std::vector<ifcopenshell::geom::converter*> kernel_pool;
|
||||
std::vector<std::unique_ptr<::logger>> worker_loggers_;
|
||||
|
||||
// The object is fetched beforehand to be sure that get() returns a valid element
|
||||
TriangulationElement* current_triangulation;
|
||||
BRepElement* current_shape_model;
|
||||
SerializedElement* current_serialization;
|
||||
triangulation_element* current_triangulation;
|
||||
brep_element* current_shape_model;
|
||||
serialized_element* current_serialization;
|
||||
|
||||
double lowest_precision_encountered;
|
||||
bool any_precision_encountered;
|
||||
@@ -148,42 +148,42 @@ namespace IfcGeom {
|
||||
int done;
|
||||
int total;
|
||||
|
||||
ifcopenshell::geometry::taxonomy::point3 bounds_min_;
|
||||
ifcopenshell::geometry::taxonomy::point3 bounds_max_;
|
||||
ifcopenshell::geom::taxonomy::point3 bounds_min_;
|
||||
ifcopenshell::geom::taxonomy::point3 bounds_max_;
|
||||
|
||||
// Should not be destructed because, destructor is blocking
|
||||
std::future<void> init_future_;
|
||||
std::array<std::chrono::high_resolution_clock::time_point, 4> time_points;
|
||||
|
||||
template <typename Fn>
|
||||
Element* create_processed_element_(Fn f) {
|
||||
element* create_processed_element_(Fn f) {
|
||||
return f();
|
||||
}
|
||||
|
||||
express::Base create_shape_model_for_next_entity();
|
||||
express::base create_shape_model_for_next_entity();
|
||||
|
||||
void create_element_(
|
||||
ifcopenshell::geometry::Converter* kernel,
|
||||
ifcopenshell::geometry::Settings settings,
|
||||
ifcopenshell::geom::converter* kernel,
|
||||
ifcopenshell::geom::settings settings,
|
||||
geometry_conversion_result* rep);
|
||||
|
||||
IfcGeom::Element* process_based_on_settings(
|
||||
ifcopenshell::geometry::Settings settings,
|
||||
IfcGeom::BRepElement* elem,
|
||||
ifcopenshell::geom::element* process_based_on_settings(
|
||||
ifcopenshell::geom::settings settings,
|
||||
ifcopenshell::geom::brep_element* elem,
|
||||
::logger& logger,
|
||||
IfcGeom::TriangulationElement* previous = nullptr);
|
||||
ifcopenshell::geom::triangulation_element* previous = nullptr);
|
||||
|
||||
void flush_worker_log(ifcopenshell::geometry::Converter* kernel);
|
||||
void flush_worker_log(ifcopenshell::geom::converter* kernel);
|
||||
|
||||
bool wait_for_element();
|
||||
|
||||
void log_timepoints() const;
|
||||
void validate_iterator_state() const;
|
||||
|
||||
ifcopenshell::geometry::taxonomy::direction3::ptr remove_offset_();
|
||||
ifcopenshell::geom::taxonomy::direction3::ptr remove_offset_();
|
||||
public:
|
||||
|
||||
Iterator(std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel>&& geometry_library, const ifcopenshell::geometry::Settings& settings, ifcopenshell::file* file, const std::vector<ifcopenshell::geometry::filter_t>& filters, int num_threads, ::logger& logger = ::logger::root())
|
||||
iterator(std::unique_ptr<ifcopenshell::geom::kernels::abstract_kernel>&& geometry_library, const ifcopenshell::geom::settings& settings, ifcopenshell::file* file, const std::vector<ifcopenshell::geom::filter_t>& filters, int num_threads, ::logger& logger = ::logger::root())
|
||||
: settings_(settings)
|
||||
, ifc_file(file)
|
||||
, filters_(filters)
|
||||
@@ -191,34 +191,34 @@ namespace IfcGeom {
|
||||
, geometry_library_(geometry_library->geometry_library())
|
||||
, logger_(logger)
|
||||
// @todo verify whether settings are correctly passed on
|
||||
, converter_(new ifcopenshell::geometry::Converter(std::move(geometry_library), ifc_file, settings_, logger_))
|
||||
, converter_(new ifcopenshell::geom::converter(std::move(geometry_library), ifc_file, settings_, logger_))
|
||||
{
|
||||
}
|
||||
|
||||
Iterator(std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel>&& geometry_library, const ifcopenshell::geometry::Settings& settings, ifcopenshell::file* file, ::logger& logger = ::logger::root())
|
||||
iterator(std::unique_ptr<ifcopenshell::geom::kernels::abstract_kernel>&& geometry_library, const ifcopenshell::geom::settings& settings, ifcopenshell::file* file, ::logger& logger = ::logger::root())
|
||||
: settings_(settings)
|
||||
, ifc_file(file)
|
||||
, num_threads_(1)
|
||||
, geometry_library_(geometry_library->geometry_library())
|
||||
, logger_(logger)
|
||||
, converter_(new ifcopenshell::geometry::Converter(std::move(geometry_library), ifc_file, settings_, logger_))
|
||||
, converter_(new ifcopenshell::geom::converter(std::move(geometry_library), ifc_file, settings_, logger_))
|
||||
{
|
||||
}
|
||||
|
||||
Iterator(std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel>&& geometry_library, const ifcopenshell::geometry::Settings& settings, ifcopenshell::file* file, int num_threads, ::logger& logger = ::logger::root())
|
||||
iterator(std::unique_ptr<ifcopenshell::geom::kernels::abstract_kernel>&& geometry_library, const ifcopenshell::geom::settings& settings, ifcopenshell::file* file, int num_threads, ::logger& logger = ::logger::root())
|
||||
: settings_(settings)
|
||||
, ifc_file(file)
|
||||
, num_threads_(num_threads)
|
||||
, geometry_library_(geometry_library->geometry_library())
|
||||
, logger_(logger)
|
||||
, converter_(new ifcopenshell::geometry::Converter(std::move(geometry_library), ifc_file, settings_, logger_))
|
||||
, converter_(new ifcopenshell::geom::converter(std::move(geometry_library), ifc_file, settings_, logger_))
|
||||
{
|
||||
}
|
||||
|
||||
~Iterator();
|
||||
~iterator();
|
||||
|
||||
std::vector<ifcopenshell::geometry::taxonomy::item::ptr> get_task_items() const {
|
||||
std::vector<ifcopenshell::geometry::taxonomy::item::ptr> items;
|
||||
std::vector<ifcopenshell::geom::taxonomy::item::ptr> get_task_items() const {
|
||||
std::vector<ifcopenshell::geom::taxonomy::item::ptr> items;
|
||||
items.reserve(tasks_.size());
|
||||
for (const auto& task : tasks_) {
|
||||
items.push_back(task.item);
|
||||
@@ -226,14 +226,14 @@ namespace IfcGeom {
|
||||
return items;
|
||||
}
|
||||
|
||||
std::vector<std::vector<express::Base>> get_task_products() const {
|
||||
std::vector<std::vector<express::Base>> products;
|
||||
std::vector<std::vector<express::base>> get_task_products() const {
|
||||
std::vector<std::vector<express::base>> products;
|
||||
for (const auto& task : tasks_) {
|
||||
if (task.is_parallel()) {
|
||||
products.push_back(task.products_2);
|
||||
} else {
|
||||
for (auto& product : task.products) {
|
||||
std::vector<express::Base> p;
|
||||
std::vector<express::base> p;
|
||||
p.push_back(product.first);
|
||||
products.push_back(p);
|
||||
}
|
||||
@@ -264,7 +264,7 @@ namespace IfcGeom {
|
||||
|
||||
size_t processed_ = 0;
|
||||
|
||||
void process_finished_rep(geometry_conversion_result* rep, ifcopenshell::geometry::Converter* kernel = nullptr);
|
||||
void process_finished_rep(geometry_conversion_result* rep, ifcopenshell::geom::converter* kernel = nullptr);
|
||||
|
||||
void process_concurrently();
|
||||
|
||||
@@ -280,28 +280,28 @@ namespace IfcGeom {
|
||||
|
||||
ifcopenshell::file* file() const { return ifc_file; }
|
||||
|
||||
const std::vector<ifcopenshell::geometry::filter_t>& filters() const { return filters_; }
|
||||
std::vector<ifcopenshell::geometry::filter_t>& filters() { return filters_; }
|
||||
const std::vector<ifcopenshell::geom::filter_t>& filters() const { return filters_; }
|
||||
std::vector<ifcopenshell::geom::filter_t>& filters() { return filters_; }
|
||||
|
||||
const ifcopenshell::geometry::taxonomy::point3& bounds_min() const { return bounds_min_; }
|
||||
const ifcopenshell::geometry::taxonomy::point3& bounds_max() const { return bounds_max_; }
|
||||
const ifcopenshell::geom::taxonomy::point3& bounds_min() const { return bounds_min_; }
|
||||
const ifcopenshell::geom::taxonomy::point3& bounds_max() const { return bounds_max_; }
|
||||
|
||||
/// Moves to the next shape representation, create its geometry, and returns the associated product.
|
||||
/// Use get() to retrieve the created geometry.
|
||||
express::Base next();
|
||||
express::base next();
|
||||
|
||||
/// Gets the representation of the current geometrical entity.
|
||||
Element* get();
|
||||
element* get();
|
||||
|
||||
/// Gets the native (Open Cascade or CGAL) representation of the current geometrical entity.
|
||||
BRepElement* get_native()
|
||||
brep_element* get_native()
|
||||
{
|
||||
return *native_task_result_iterator_;
|
||||
}
|
||||
|
||||
const Element* get_object(int id);
|
||||
const element* get_object(int id);
|
||||
|
||||
express::Base create();
|
||||
express::base create();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ set_target_properties(geometry_serializer PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${geometry_serialization_plugin_runtime_dir}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${geometry_serialization_plugin_runtime_dir}"
|
||||
)
|
||||
target_link_libraries(geometry_serializer plugin IfcGeom IfcParse ${OpenCASCADE_LIBRARIES})
|
||||
target_link_libraries(geometry_serializer plugin IfcGeom IfcParse geometry_kernel_opencascade ${OpenCASCADE_LIBRARIES})
|
||||
set(IFCOPENSHELL_LIBRARIES ${IFCOPENSHELL_LIBRARIES} "geometry_serializer")
|
||||
set(IFCOPENSHELL_LIBRARIES ${IFCOPENSHELL_LIBRARIES} PARENT_SCOPE)
|
||||
|
||||
|
||||
@@ -12,12 +12,12 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
IfcGeom::opencascade_geometry_ifc_writer_registry& IfcGeom::opencascade_geometry_ifc_writer_registry_instance() {
|
||||
ifcopenshell::geom::opencascade_geometry_ifc_writer_registry& ifcopenshell::geom::opencascade_geometry_ifc_writer_registry_instance() {
|
||||
static opencascade_geometry_ifc_writer_registry registry;
|
||||
return registry;
|
||||
}
|
||||
|
||||
void IfcGeom::opencascade_geometry_ifc_writer_registry::bind(const std::string& schema_name, serialise_fn serialise, tesselate_fn tesselate, const ifcopenshell::plugin::module& module) {
|
||||
void ifcopenshell::geom::opencascade_geometry_ifc_writer_registry::bind(const std::string& schema_name, serialise_fn serialise, tesselate_fn tesselate, const ifcopenshell::plugin::module& module) {
|
||||
entry entry;
|
||||
entry.serialise_ = serialise;
|
||||
entry.tesselate_ = tesselate;
|
||||
@@ -25,7 +25,7 @@ void IfcGeom::opencascade_geometry_ifc_writer_registry::bind(const std::string&
|
||||
entries_[writer_schema_key(schema_name)] = entry;
|
||||
}
|
||||
|
||||
express::Base IfcGeom::opencascade_geometry_ifc_writer_registry::tesselate(ifcopenshell::file& f, const ConversionResultShape& shape, double deflection) const {
|
||||
express::base ifcopenshell::geom::opencascade_geometry_ifc_writer_registry::tesselate(ifcopenshell::file& f, const conversion_result_shape& shape, double deflection) const {
|
||||
auto iter = entries_.find(writer_schema_key(f.schema()->name()));
|
||||
if (iter == entries_.end()) {
|
||||
load_opencascade_geometry_ifc_writer_plugin(const_cast<opencascade_geometry_ifc_writer_registry&>(*this), f.schema()->name());
|
||||
@@ -37,7 +37,7 @@ express::Base IfcGeom::opencascade_geometry_ifc_writer_registry::tesselate(ifcop
|
||||
return iter->second.tesselate_(f, shape, deflection);
|
||||
}
|
||||
|
||||
express::Base IfcGeom::opencascade_geometry_ifc_writer_registry::serialise(ifcopenshell::file& f, const ConversionResultShape& shape, bool advanced) const {
|
||||
express::base ifcopenshell::geom::opencascade_geometry_ifc_writer_registry::serialise(ifcopenshell::file& f, const conversion_result_shape& shape, bool advanced) const {
|
||||
auto iter = entries_.find(writer_schema_key(f.schema()->name()));
|
||||
if (iter == entries_.end()) {
|
||||
load_opencascade_geometry_ifc_writer_plugin(const_cast<opencascade_geometry_ifc_writer_registry&>(*this), f.schema()->name());
|
||||
@@ -49,20 +49,20 @@ express::Base IfcGeom::opencascade_geometry_ifc_writer_registry::serialise(ifcop
|
||||
return iter->second.serialise_(f, shape, advanced);
|
||||
}
|
||||
|
||||
express::Base IfcGeom::tesselate(ifcopenshell::file& f, const ConversionResultShape& shape, double deflection) {
|
||||
express::base ifcopenshell::geom::tesselate(ifcopenshell::file& f, const conversion_result_shape& shape, double deflection) {
|
||||
return opencascade_geometry_ifc_writer_registry_instance().tesselate(f, shape, deflection);
|
||||
}
|
||||
|
||||
express::Base IfcGeom::serialise(ifcopenshell::file& f, const ConversionResultShape& shape, bool advanced) {
|
||||
express::base ifcopenshell::geom::serialise(ifcopenshell::file& f, const conversion_result_shape& shape, bool advanced) {
|
||||
return opencascade_geometry_ifc_writer_registry_instance().serialise(f, shape, advanced);
|
||||
}
|
||||
|
||||
express::Base IfcGeom::tesselate(ifcopenshell::file& f, const TopoDS_Shape& shape, double deflection) {
|
||||
ifcopenshell::geometry::OpenCascadeShape converted(shape);
|
||||
express::base ifcopenshell::geom::tesselate(ifcopenshell::file& f, const TopoDS_Shape& shape, double deflection) {
|
||||
ifcopenshell::geom::open_cascade_shape converted(shape);
|
||||
return tesselate(f, converted, deflection);
|
||||
}
|
||||
|
||||
express::Base IfcGeom::serialise(ifcopenshell::file& f, const TopoDS_Shape& shape, bool advanced) {
|
||||
ifcopenshell::geometry::OpenCascadeShape converted(shape);
|
||||
express::base ifcopenshell::geom::serialise(ifcopenshell::file& f, const TopoDS_Shape& shape, bool advanced) {
|
||||
ifcopenshell::geom::open_cascade_shape converted(shape);
|
||||
return serialise(f, converted, advanced);
|
||||
}
|
||||
|
||||
@@ -18,15 +18,15 @@ namespace ifcopenshell {
|
||||
class file;
|
||||
}
|
||||
|
||||
namespace IfcGeom {
|
||||
namespace ifcopenshell::geom {
|
||||
class IFC_GEOMSERIALIZATION_API opencascade_geometry_ifc_writer_registry {
|
||||
public:
|
||||
typedef boost::function3<express::Base, ifcopenshell::file&, const ConversionResultShape&, double> tesselate_fn;
|
||||
typedef boost::function3<express::Base, ifcopenshell::file&, const ConversionResultShape&, bool> serialise_fn;
|
||||
typedef boost::function3<express::base, ifcopenshell::file&, const conversion_result_shape&, double> tesselate_fn;
|
||||
typedef boost::function3<express::base, ifcopenshell::file&, const conversion_result_shape&, bool> serialise_fn;
|
||||
|
||||
void bind(const std::string& schema_name, serialise_fn serialise, tesselate_fn tesselate, const ifcopenshell::plugin::module& module = ifcopenshell::plugin::module());
|
||||
express::Base tesselate(ifcopenshell::file& f, const ConversionResultShape& shape, double deflection) const;
|
||||
express::Base serialise(ifcopenshell::file& f, const ConversionResultShape& shape, bool advanced) const;
|
||||
express::base tesselate(ifcopenshell::file& f, const conversion_result_shape& shape, double deflection) const;
|
||||
express::base serialise(ifcopenshell::file& f, const conversion_result_shape& shape, bool advanced) const;
|
||||
|
||||
private:
|
||||
struct entry {
|
||||
@@ -40,10 +40,10 @@ private:
|
||||
|
||||
IFC_GEOMSERIALIZATION_API opencascade_geometry_ifc_writer_registry& opencascade_geometry_ifc_writer_registry_instance();
|
||||
|
||||
IFC_GEOMSERIALIZATION_API express::Base tesselate(ifcopenshell::file& f, const ConversionResultShape& shape, double deflection);
|
||||
IFC_GEOMSERIALIZATION_API express::Base serialise(ifcopenshell::file& f, const ConversionResultShape& shape, bool advanced);
|
||||
IFC_GEOMSERIALIZATION_API express::Base tesselate(ifcopenshell::file& f, const TopoDS_Shape& shape, double deflection);
|
||||
IFC_GEOMSERIALIZATION_API express::Base serialise(ifcopenshell::file& f, const TopoDS_Shape& shape, bool advanced);
|
||||
} // namespace IfcGeom
|
||||
IFC_GEOMSERIALIZATION_API express::base tesselate(ifcopenshell::file& f, const conversion_result_shape& shape, double deflection);
|
||||
IFC_GEOMSERIALIZATION_API express::base serialise(ifcopenshell::file& f, const conversion_result_shape& shape, bool advanced);
|
||||
IFC_GEOMSERIALIZATION_API express::base tesselate(ifcopenshell::file& f, const TopoDS_Shape& shape, double deflection);
|
||||
IFC_GEOMSERIALIZATION_API express::base serialise(ifcopenshell::file& f, const TopoDS_Shape& shape, bool advanced);
|
||||
} // namespace ifcopenshell::geom
|
||||
|
||||
#endif
|
||||
|
||||
@@ -31,11 +31,11 @@ namespace {
|
||||
constexpr const char* opencascade_geometry_ifc_writer_plugin_prefix = "geometry.writer.";
|
||||
}
|
||||
|
||||
const char* IfcGeom::opencascade_geometry_ifc_writer_plugin_registration_symbol() {
|
||||
const char* ifcopenshell::geom::opencascade_geometry_ifc_writer_plugin_registration_symbol() {
|
||||
return "ifcopenshell_register_opencascade_geometry_ifc_writer_plugin_v1";
|
||||
}
|
||||
|
||||
ifcopenshell::plugin::metadata IfcGeom::opencascade_geometry_ifc_writer_plugin_metadata(const std::string& schema_name) {
|
||||
ifcopenshell::plugin::metadata ifcopenshell::geom::opencascade_geometry_ifc_writer_plugin_metadata(const std::string& schema_name) {
|
||||
ifcopenshell::plugin::metadata metadata;
|
||||
metadata.kind_ = ifcopenshell::plugin::kind::opencascade_geometry_ifc_writer;
|
||||
metadata.id = opencascade_geometry_ifc_writer_plugin_prefix + boost::to_lower_copy(schema_name);
|
||||
@@ -43,11 +43,11 @@ ifcopenshell::plugin::metadata IfcGeom::opencascade_geometry_ifc_writer_plugin_m
|
||||
return metadata;
|
||||
}
|
||||
|
||||
std::filesystem::path IfcGeom::opencascade_geometry_ifc_writer_plugin_directory() {
|
||||
return ifcopenshell::plugin::module_directory(reinterpret_cast<const void*>(&IfcGeom::load_opencascade_geometry_ifc_writer_plugins));
|
||||
std::filesystem::path ifcopenshell::geom::opencascade_geometry_ifc_writer_plugin_directory() {
|
||||
return ifcopenshell::plugin::module_directory(reinterpret_cast<const void*>(&ifcopenshell::geom::load_opencascade_geometry_ifc_writer_plugins));
|
||||
}
|
||||
|
||||
void IfcGeom::load_opencascade_geometry_ifc_writer_plugins(opencascade_geometry_ifc_writer_registry& registry) {
|
||||
void ifcopenshell::geom::load_opencascade_geometry_ifc_writer_plugins(opencascade_geometry_ifc_writer_registry& registry) {
|
||||
ifcopenshell::plugin::manager manager;
|
||||
ifcopenshell::plugin::add_search_paths_or_default(manager, &opencascade_geometry_ifc_writer_plugin_directory);
|
||||
|
||||
@@ -62,7 +62,7 @@ void IfcGeom::load_opencascade_geometry_ifc_writer_plugins(opencascade_geometry_
|
||||
}
|
||||
}
|
||||
|
||||
bool IfcGeom::load_opencascade_geometry_ifc_writer_plugin(opencascade_geometry_ifc_writer_registry& registry, const std::string& schema_name) {
|
||||
bool ifcopenshell::geom::load_opencascade_geometry_ifc_writer_plugin(opencascade_geometry_ifc_writer_registry& registry, const std::string& schema_name) {
|
||||
ifcopenshell::plugin::manager manager;
|
||||
ifcopenshell::plugin::add_search_paths_or_default(manager, &opencascade_geometry_ifc_writer_plugin_directory);
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
namespace IfcGeom {
|
||||
namespace ifcopenshell::geom {
|
||||
|
||||
typedef void register_opencascade_geometry_ifc_writer_plugin_fn(opencascade_geometry_ifc_writer_registry&, const ifcopenshell::plugin::module&);
|
||||
|
||||
|
||||
@@ -622,7 +622,7 @@ int convert_to_ifc(ifcopenshell::file& f, const TopoDS_Shape& s, U& item, bool a
|
||||
if (convert_to_ifc(f, TopoDS::Face(exp.Current()), fa, advanced)) {
|
||||
faces.push_back(fa);
|
||||
} else {
|
||||
std::set<express::Base> created;
|
||||
std::set<express::base> created;
|
||||
for (auto& face : faces) {
|
||||
auto resources = f.traverse(face);
|
||||
created.insert(resources.begin(), resources.end());
|
||||
@@ -640,7 +640,7 @@ int convert_to_ifc(ifcopenshell::file& f, const TopoDS_Shape& s, U& item, bool a
|
||||
return faces.size();
|
||||
}
|
||||
|
||||
express::Base POSTFIX_SCHEMA(serialise)(ifcopenshell::file& f, const TopoDS_Shape& shape, bool advanced) {
|
||||
express::base POSTFIX_SCHEMA(serialise)(ifcopenshell::file& f, const TopoDS_Shape& shape, bool advanced) {
|
||||
|
||||
#ifndef SCHEMA_HAS_IfcAdvancedBrep
|
||||
advanced = false;
|
||||
@@ -648,7 +648,7 @@ express::Base POSTFIX_SCHEMA(serialise)(ifcopenshell::file& f, const TopoDS_Shap
|
||||
|
||||
for (TopExp_Explorer exp(shape, TopAbs_COMPSOLID); exp.More();) {
|
||||
/// @todo CompSolids are not supported
|
||||
return express::Base{};
|
||||
return express::base{};
|
||||
}
|
||||
|
||||
IfcSchema::IfcRepresentation rep;
|
||||
@@ -661,7 +661,7 @@ express::Base POSTFIX_SCHEMA(serialise)(ifcopenshell::file& f, const TopoDS_Shap
|
||||
for (TopExp_Explorer exp2(exp.Current(), TopAbs_SHELL); exp2.More(); exp2.Next()) {
|
||||
IfcSchema::IfcClosedShell shell;
|
||||
if (!convert_to_ifc(f, exp2.Current(), shell, advanced)) {
|
||||
return express::Base{};
|
||||
return express::base{};
|
||||
}
|
||||
/// @todo Are shells always in this order or does Orientation() needs to be checked?
|
||||
/// > #4216, no, consider using BRepClass3d::OuterShell()
|
||||
@@ -714,7 +714,7 @@ express::Base POSTFIX_SCHEMA(serialise)(ifcopenshell::file& f, const TopoDS_Shap
|
||||
for (TopExp_Explorer exp(shape, TopAbs_SHELL); exp.More(); exp.Next()) {
|
||||
IfcSchema::IfcOpenShell shell;
|
||||
if (!convert_to_ifc(f, exp.Current(), shell, advanced)) {
|
||||
return express::Base{};
|
||||
return express::base{};
|
||||
}
|
||||
shells.push_back(shell);
|
||||
}
|
||||
@@ -750,18 +750,18 @@ express::Base POSTFIX_SCHEMA(serialise)(ifcopenshell::file& f, const TopoDS_Shap
|
||||
// they are not commonly top-level geometrical descriptions in IFC.
|
||||
// Also note that edges are written as trimmed curves rather than edges.
|
||||
|
||||
std::vector<express::Entity> edges;
|
||||
std::vector<express::entity> edges;
|
||||
|
||||
for (TopExp_Explorer exp(shape, TopAbs_EDGE); exp.More(); exp.Next()) {
|
||||
IfcSchema::IfcCurve c;
|
||||
if (!convert_to_ifc(f, TopoDS::Edge(exp.Current()), c, advanced)) {
|
||||
return express::Base{};
|
||||
return express::base{};
|
||||
}
|
||||
edges.push_back(c);
|
||||
}
|
||||
|
||||
if (edges.size() == 0) {
|
||||
return express::Base{};
|
||||
return express::base{};
|
||||
} else if (edges.size() == 1) {
|
||||
auto srep = f.create<IfcSchema::IfcShapeRepresentation>();
|
||||
srep.setRepresentationIdentifier("Axis");
|
||||
@@ -791,7 +791,7 @@ express::Base POSTFIX_SCHEMA(serialise)(ifcopenshell::file& f, const TopoDS_Shap
|
||||
return pds;
|
||||
}
|
||||
|
||||
express::Base POSTFIX_SCHEMA(tesselate)(ifcopenshell::file& f, const TopoDS_Shape& shape, double deflection) {
|
||||
express::base POSTFIX_SCHEMA(tesselate)(ifcopenshell::file& f, const TopoDS_Shape& shape, double deflection) {
|
||||
// @todo use triangulated face set in ifc4+ schema
|
||||
|
||||
BRepMesh_IncrementalMesh(shape, deflection);
|
||||
|
||||
@@ -25,28 +25,28 @@
|
||||
|
||||
#include <boost/dll/alias.hpp>
|
||||
|
||||
express::Base POSTFIX_SCHEMA(serialise)(ifcopenshell::file& f, const TopoDS_Shape& shape, bool advanced);
|
||||
express::Base POSTFIX_SCHEMA(tesselate)(ifcopenshell::file& f, const TopoDS_Shape& shape, double deflection);
|
||||
express::base POSTFIX_SCHEMA(serialise)(ifcopenshell::file& f, const TopoDS_Shape& shape, bool advanced);
|
||||
express::base POSTFIX_SCHEMA(tesselate)(ifcopenshell::file& f, const TopoDS_Shape& shape, double deflection);
|
||||
|
||||
namespace {
|
||||
const ifcopenshell::geometry::OpenCascadeShape& require_opencascade_shape(const IfcGeom::ConversionResultShape& shape) {
|
||||
const auto* oc_shape = dynamic_cast<const ifcopenshell::geometry::OpenCascadeShape*>(&shape);
|
||||
const ifcopenshell::geom::open_cascade_shape& require_opencascade_shape(const ifcopenshell::geom::conversion_result_shape& shape) {
|
||||
const auto* oc_shape = dynamic_cast<const ifcopenshell::geom::open_cascade_shape*>(&shape);
|
||||
if (!oc_shape) {
|
||||
throw ifcopenshell::exception("OpenCascade geometry IFC writer requires an opencascade conversion result shape");
|
||||
}
|
||||
return *oc_shape;
|
||||
}
|
||||
|
||||
express::Base serialise_adapter(ifcopenshell::file& f, const IfcGeom::ConversionResultShape& shape, bool advanced) {
|
||||
express::base serialise_adapter(ifcopenshell::file& f, const ifcopenshell::geom::conversion_result_shape& shape, bool advanced) {
|
||||
return POSTFIX_SCHEMA(serialise)(f, require_opencascade_shape(shape).shape(), advanced);
|
||||
}
|
||||
|
||||
express::Base tesselate_adapter(ifcopenshell::file& f, const IfcGeom::ConversionResultShape& shape, double deflection) {
|
||||
express::base tesselate_adapter(ifcopenshell::file& f, const ifcopenshell::geom::conversion_result_shape& shape, double deflection) {
|
||||
return POSTFIX_SCHEMA(tesselate)(f, require_opencascade_shape(shape).shape(), deflection);
|
||||
}
|
||||
}
|
||||
|
||||
namespace IfcGeom {
|
||||
namespace ifcopenshell::geom {
|
||||
namespace opencascade_geometry_ifc_writer_plugin {
|
||||
|
||||
ifcopenshell::plugin::abi_info plugin_abi() {
|
||||
@@ -64,6 +64,6 @@ namespace IfcGeom {
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_DLL_ALIAS(IfcGeom::opencascade_geometry_ifc_writer_plugin::plugin_abi, ifcopenshell_plugin_abi_v1)
|
||||
BOOST_DLL_ALIAS(IfcGeom::opencascade_geometry_ifc_writer_plugin::plugin_metadata, ifcopenshell_plugin_metadata_v1)
|
||||
BOOST_DLL_ALIAS(IfcGeom::opencascade_geometry_ifc_writer_plugin::register_plugin, ifcopenshell_register_opencascade_geometry_ifc_writer_plugin_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geom::opencascade_geometry_ifc_writer_plugin::plugin_abi, ifcopenshell_plugin_abi_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geom::opencascade_geometry_ifc_writer_plugin::plugin_metadata, ifcopenshell_plugin_metadata_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geom::opencascade_geometry_ifc_writer_plugin::register_plugin, ifcopenshell_register_opencascade_geometry_ifc_writer_plugin_v1)
|
||||
|
||||
@@ -23,11 +23,11 @@
|
||||
#include "ifc_geom_api.h"
|
||||
#include "../ifcparse/file.h"
|
||||
|
||||
class IFC_GEOM_API Serializer {
|
||||
class IFC_GEOM_API serializer {
|
||||
::logger& logger_;
|
||||
public:
|
||||
explicit Serializer(::logger& logger = ::logger::root()) : logger_(logger) {}
|
||||
virtual ~Serializer() {}
|
||||
explicit serializer(::logger& logger = ::logger::root()) : logger_(logger) {}
|
||||
virtual ~serializer() {}
|
||||
|
||||
::logger& logger() const { return logger_; }
|
||||
|
||||
|
||||
@@ -8,55 +8,55 @@
|
||||
|
||||
namespace pt = boost::property_tree;
|
||||
|
||||
static std::map<std::string, ifcopenshell::geometry::taxonomy::style::ptr> default_materials;
|
||||
static ifcopenshell::geometry::taxonomy::style::ptr default_material;
|
||||
static std::map<std::string, ifcopenshell::geom::taxonomy::style::ptr> default_materials;
|
||||
static ifcopenshell::geom::taxonomy::style::ptr default_material;
|
||||
static bool default_materials_initialized = false;
|
||||
|
||||
void InitDefaultMaterials() {
|
||||
default_materials.insert(std::make_pair("IfcSite", std::make_shared<ifcopenshell::geometry::taxonomy::style>("IfcSite")));
|
||||
default_materials["IfcSite"]->diffuse = ifcopenshell::geometry::taxonomy::colour(0.75, 0.8, 0.65);
|
||||
default_materials.insert(std::make_pair("IfcSite", std::make_shared<ifcopenshell::geom::taxonomy::style>("IfcSite")));
|
||||
default_materials["IfcSite"]->diffuse = ifcopenshell::geom::taxonomy::colour(0.75, 0.8, 0.65);
|
||||
|
||||
default_materials.insert(std::make_pair("IfcSlab", std::make_shared<ifcopenshell::geometry::taxonomy::style>("IfcSlab")));
|
||||
default_materials["IfcSlab"]->diffuse = ifcopenshell::geometry::taxonomy::colour(0.4, 0.4, 0.4);
|
||||
default_materials.insert(std::make_pair("IfcSlab", std::make_shared<ifcopenshell::geom::taxonomy::style>("IfcSlab")));
|
||||
default_materials["IfcSlab"]->diffuse = ifcopenshell::geom::taxonomy::colour(0.4, 0.4, 0.4);
|
||||
|
||||
default_materials.insert(std::make_pair("IfcWallStandardCase", std::make_shared<ifcopenshell::geometry::taxonomy::style>("IfcWallStandardCase")));
|
||||
default_materials["IfcWallStandardCase"]->diffuse = ifcopenshell::geometry::taxonomy::colour(0.9, 0.9, 0.9);
|
||||
default_materials.insert(std::make_pair("IfcWallStandardCase", std::make_shared<ifcopenshell::geom::taxonomy::style>("IfcWallStandardCase")));
|
||||
default_materials["IfcWallStandardCase"]->diffuse = ifcopenshell::geom::taxonomy::colour(0.9, 0.9, 0.9);
|
||||
|
||||
default_materials.insert(std::make_pair("IfcWall", std::make_shared<ifcopenshell::geometry::taxonomy::style>("IfcWall")));
|
||||
default_materials["IfcWall"]->diffuse = ifcopenshell::geometry::taxonomy::colour(0.9, 0.9, 0.9);
|
||||
default_materials.insert(std::make_pair("IfcWall", std::make_shared<ifcopenshell::geom::taxonomy::style>("IfcWall")));
|
||||
default_materials["IfcWall"]->diffuse = ifcopenshell::geom::taxonomy::colour(0.9, 0.9, 0.9);
|
||||
|
||||
default_materials.insert(std::make_pair("IfcWindow", std::make_shared<ifcopenshell::geometry::taxonomy::style>("IfcWindow")));
|
||||
default_materials["IfcWindow"]->diffuse = ifcopenshell::geometry::taxonomy::colour(0.75, 0.8, 0.75);
|
||||
default_materials.insert(std::make_pair("IfcWindow", std::make_shared<ifcopenshell::geom::taxonomy::style>("IfcWindow")));
|
||||
default_materials["IfcWindow"]->diffuse = ifcopenshell::geom::taxonomy::colour(0.75, 0.8, 0.75);
|
||||
default_materials["IfcWindow"]->transparency = 0.3;
|
||||
|
||||
default_materials.insert(std::make_pair("IfcDoor", std::make_shared<ifcopenshell::geometry::taxonomy::style>("IfcDoor")));
|
||||
default_materials["IfcDoor"]->diffuse = ifcopenshell::geometry::taxonomy::colour(0.55, 0.3, 0.15);
|
||||
default_materials.insert(std::make_pair("IfcDoor", std::make_shared<ifcopenshell::geom::taxonomy::style>("IfcDoor")));
|
||||
default_materials["IfcDoor"]->diffuse = ifcopenshell::geom::taxonomy::colour(0.55, 0.3, 0.15);
|
||||
|
||||
default_materials.insert(std::make_pair("IfcBeam", std::make_shared<ifcopenshell::geometry::taxonomy::style>("IfcBeam")));
|
||||
default_materials["IfcBeam"]->diffuse = ifcopenshell::geometry::taxonomy::colour(0.75, 0.7, 0.7);
|
||||
default_materials.insert(std::make_pair("IfcBeam", std::make_shared<ifcopenshell::geom::taxonomy::style>("IfcBeam")));
|
||||
default_materials["IfcBeam"]->diffuse = ifcopenshell::geom::taxonomy::colour(0.75, 0.7, 0.7);
|
||||
|
||||
default_materials.insert(std::make_pair("IfcRailing", std::make_shared<ifcopenshell::geometry::taxonomy::style>("IfcRailing")));
|
||||
default_materials["IfcRailing"]->diffuse = ifcopenshell::geometry::taxonomy::colour(0.65, 0.6, 0.6);
|
||||
default_materials.insert(std::make_pair("IfcRailing", std::make_shared<ifcopenshell::geom::taxonomy::style>("IfcRailing")));
|
||||
default_materials["IfcRailing"]->diffuse = ifcopenshell::geom::taxonomy::colour(0.65, 0.6, 0.6);
|
||||
|
||||
default_materials.insert(std::make_pair("IfcMember", std::make_shared<ifcopenshell::geometry::taxonomy::style>("IfcMember")));
|
||||
default_materials["IfcMember"]->diffuse = ifcopenshell::geometry::taxonomy::colour(0.65, 0.6, 0.6);
|
||||
default_materials.insert(std::make_pair("IfcMember", std::make_shared<ifcopenshell::geom::taxonomy::style>("IfcMember")));
|
||||
default_materials["IfcMember"]->diffuse = ifcopenshell::geom::taxonomy::colour(0.65, 0.6, 0.6);
|
||||
|
||||
default_materials.insert(std::make_pair("IfcPlate", std::make_shared<ifcopenshell::geometry::taxonomy::style>("IfcPlate")));
|
||||
default_materials["IfcPlate"]->diffuse = ifcopenshell::geometry::taxonomy::colour(0.8, 0.8, 0.8);
|
||||
default_materials.insert(std::make_pair("IfcPlate", std::make_shared<ifcopenshell::geom::taxonomy::style>("IfcPlate")));
|
||||
default_materials["IfcPlate"]->diffuse = ifcopenshell::geom::taxonomy::colour(0.8, 0.8, 0.8);
|
||||
|
||||
default_materials.insert(std::make_pair("IfcSpace", std::make_shared<ifcopenshell::geometry::taxonomy::style>("IfcSpace")));
|
||||
default_materials["IfcSpace"]->diffuse = ifcopenshell::geometry::taxonomy::colour(0.65, 0.75, 0.8);
|
||||
default_materials.insert(std::make_pair("IfcSpace", std::make_shared<ifcopenshell::geom::taxonomy::style>("IfcSpace")));
|
||||
default_materials["IfcSpace"]->diffuse = ifcopenshell::geom::taxonomy::colour(0.65, 0.75, 0.8);
|
||||
default_materials["IfcSpace"]->transparency = 0.8;
|
||||
|
||||
default_material = std::make_shared<ifcopenshell::geometry::taxonomy::style>("DefaultMaterial");
|
||||
default_material->diffuse = ifcopenshell::geometry::taxonomy::colour(0.7, 0.7, 0.7);
|
||||
default_material = std::make_shared<ifcopenshell::geom::taxonomy::style>("DefaultMaterial");
|
||||
default_material->diffuse = ifcopenshell::geom::taxonomy::colour(0.7, 0.7, 0.7);
|
||||
|
||||
default_materials_initialized = true;
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::taxonomy::colour read_colour_component(const boost::optional<pt::ptree&> list) {
|
||||
ifcopenshell::geom::taxonomy::colour read_colour_component(const boost::optional<pt::ptree&> list) {
|
||||
if (!list) {
|
||||
return ifcopenshell::geometry::taxonomy::colour();
|
||||
return ifcopenshell::geom::taxonomy::colour();
|
||||
}
|
||||
double rgb[3];
|
||||
int i = 0;
|
||||
@@ -70,10 +70,10 @@ ifcopenshell::geometry::taxonomy::colour read_colour_component(const boost::opti
|
||||
if (i != 3) {
|
||||
throw std::runtime_error("rgb array less than 3 elements large (was " + std::to_string(i) + ")");
|
||||
}
|
||||
return ifcopenshell::geometry::taxonomy::colour(rgb[0], rgb[1], rgb[2]);
|
||||
return ifcopenshell::geom::taxonomy::colour(rgb[0], rgb[1], rgb[2]);
|
||||
}
|
||||
|
||||
void IfcGeom::set_default_style_file(const std::string& json_file) {
|
||||
void ifcopenshell::geom::set_default_style_file(const std::string& json_file) {
|
||||
if (!default_materials_initialized) InitDefaultMaterials();
|
||||
default_materials.clear();
|
||||
|
||||
@@ -83,7 +83,7 @@ void IfcGeom::set_default_style_file(const std::string& json_file) {
|
||||
|
||||
for (pt::ptree::value_type &material_pair : root) {
|
||||
std::string name = material_pair.first;
|
||||
default_materials.insert(std::make_pair(name, std::make_shared<ifcopenshell::geometry::taxonomy::style>(name)));
|
||||
default_materials.insert(std::make_pair(name, std::make_shared<ifcopenshell::geom::taxonomy::style>(name)));
|
||||
|
||||
pt::ptree material = material_pair.second;
|
||||
auto diffuse = material.get_child_optional("diffuse");
|
||||
@@ -112,7 +112,7 @@ void IfcGeom::set_default_style_file(const std::string& json_file) {
|
||||
}
|
||||
}
|
||||
|
||||
const ifcopenshell::geometry::taxonomy::style::ptr& IfcGeom::get_default_style(const std::string& s) {
|
||||
const ifcopenshell::geom::taxonomy::style::ptr& ifcopenshell::geom::get_default_style(const std::string& s) {
|
||||
static std::mutex m;
|
||||
std::lock_guard<std::mutex> lk(m);
|
||||
|
||||
@@ -125,7 +125,7 @@ const ifcopenshell::geometry::taxonomy::style::ptr& IfcGeom::get_default_style(c
|
||||
return it->second;
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::taxonomy::style::ptr& IfcGeom::update_default_style(const std::string& s) {
|
||||
ifcopenshell::geom::taxonomy::style::ptr& ifcopenshell::geom::update_default_style(const std::string& s) {
|
||||
if (!default_materials_initialized) InitDefaultMaterials();
|
||||
auto it = default_materials.find(s);
|
||||
if (it == default_materials.end()) {
|
||||
|
||||
@@ -12,18 +12,18 @@ namespace {
|
||||
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::impl::mapping_registry& ifcopenshell::geometry::impl::mapping_registry_instance() {
|
||||
ifcopenshell::geom::impl::mapping_registry& ifcopenshell::geom::impl::mapping_registry_instance() {
|
||||
static mapping_registry registry;
|
||||
return registry;
|
||||
}
|
||||
|
||||
void ifcopenshell::geometry::impl::mapping_registry::bind(const std::string& schema_name, ifcopenshell::geometry::impl::mapping_fn fn, const plugin::module& module) {
|
||||
void ifcopenshell::geom::impl::mapping_registry::bind(const std::string& schema_name, ifcopenshell::geom::impl::mapping_fn fn, const plugin::module& module) {
|
||||
auto& entry = entries_[mapping_key(schema_name)];
|
||||
entry.fn_ = fn;
|
||||
entry.module_ = module.meta().id.empty() ? plugin::module(mapping_plugin_metadata(schema_name)) : module;
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::abstract_mapping* ifcopenshell::geometry::impl::mapping_registry::construct(ifcopenshell::file* file, Settings& s, ::logger& log) {
|
||||
ifcopenshell::geom::abstract_mapping* ifcopenshell::geom::impl::mapping_registry::construct(ifcopenshell::file* file, ifcopenshell::geom::settings& settings, ::logger& log) {
|
||||
const std::string schema_name_lower = boost::to_lower_copy(file->schema()->name());
|
||||
auto it = entries_.find(schema_name_lower);
|
||||
if (it == entries_.end()) {
|
||||
@@ -33,7 +33,7 @@ ifcopenshell::geometry::abstract_mapping* ifcopenshell::geometry::impl::mapping_
|
||||
if (it == entries_.end()) {
|
||||
throw ifcopenshell::exception("No geometry mapping registered for " + schema_name_lower);
|
||||
}
|
||||
auto new_mapping = it->second.fn_(file, s, log);
|
||||
auto new_mapping = it->second.fn_(file, settings, log);
|
||||
try {
|
||||
new_mapping->initialize_settings();
|
||||
} catch (const std::exception& e) {
|
||||
@@ -43,19 +43,19 @@ ifcopenshell::geometry::abstract_mapping* ifcopenshell::geometry::impl::mapping_
|
||||
return new_mapping;
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::impl::MappingFactoryImplementation& ifcopenshell::geometry::impl::mapping_implementations() {
|
||||
static MappingFactoryImplementation impl;
|
||||
ifcopenshell::geom::impl::mapping_factory_implementation& ifcopenshell::geom::impl::mapping_implementations() {
|
||||
static mapping_factory_implementation impl;
|
||||
return impl;
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::impl::MappingFactoryImplementation::MappingFactoryImplementation() {
|
||||
ifcopenshell::geom::impl::mapping_factory_implementation::mapping_factory_implementation() {
|
||||
mapping_registry_instance();
|
||||
}
|
||||
|
||||
void ifcopenshell::geometry::impl::MappingFactoryImplementation::bind(const std::string& schema_name, ifcopenshell::geometry::impl::mapping_fn fn) {
|
||||
void ifcopenshell::geom::impl::mapping_factory_implementation::bind(const std::string& schema_name, ifcopenshell::geom::impl::mapping_fn fn) {
|
||||
mapping_registry_instance().bind(schema_name, fn, plugin::module(mapping_plugin_metadata(schema_name)));
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::abstract_mapping* ifcopenshell::geometry::impl::MappingFactoryImplementation::construct(ifcopenshell::file* file, Settings& s, ::logger& log) {
|
||||
return mapping_registry_instance().construct(file, s, log);
|
||||
ifcopenshell::geom::abstract_mapping* ifcopenshell::geom::impl::mapping_factory_implementation::construct(ifcopenshell::file* file, ifcopenshell::geom::settings& settings, ::logger& log) {
|
||||
return mapping_registry_instance().construct(file, settings, log);
|
||||
}
|
||||
|
||||
@@ -33,46 +33,46 @@
|
||||
|
||||
namespace ifcopenshell {
|
||||
|
||||
namespace geometry {
|
||||
namespace geom {
|
||||
|
||||
struct IFC_GEOM_API geometry_conversion_task {
|
||||
int index;
|
||||
express::Base representation;
|
||||
std::vector<express::Base> products;
|
||||
express::base representation;
|
||||
std::vector<express::base> products;
|
||||
};
|
||||
|
||||
/// The filter function (free or member function) or function object (use boost::ref() to reference to it)
|
||||
/// should return true if the geometry for the product is wanted to be included in the output.
|
||||
/// http://www.boost.org/doc/libs/1_62_0/doc/html/function/tutorial.html
|
||||
typedef boost::function<bool(const express::Base&)> filter_t;
|
||||
typedef boost::function<bool(const express::base&)> filter_t;
|
||||
|
||||
class IFC_GEOM_API abstract_mapping {
|
||||
protected:
|
||||
Settings settings_;
|
||||
ifcopenshell::geom::settings settings_;
|
||||
::logger& logger_;
|
||||
|
||||
bool use_caching_ = true;
|
||||
|
||||
public:
|
||||
abstract_mapping(Settings& s, ::logger& logger = ::logger::root()) : settings_(s), logger_(logger) {}
|
||||
abstract_mapping(ifcopenshell::geom::settings& settings, ::logger& logger = ::logger::root()) : settings_(settings), logger_(logger) {}
|
||||
virtual ~abstract_mapping() {}
|
||||
|
||||
virtual ifcopenshell::geometry::taxonomy::ptr map(const express::Base&) = 0;
|
||||
virtual ifcopenshell::geom::taxonomy::ptr map(const express::base&) = 0;
|
||||
virtual void get_representations(std::vector<geometry_conversion_task>& tasks, std::vector<filter_t>& filters) = 0;
|
||||
virtual express::Base get_decomposing_entity(const express::Base& product, bool include_openings = true) = 0;
|
||||
virtual std::map<std::string, express::Base> get_layers(const express::Base&) = 0;
|
||||
virtual std::vector<express::Base> find_openings(const express::Base&) = 0;
|
||||
virtual express::base get_decomposing_entity(const express::base& product, bool include_openings = true) = 0;
|
||||
virtual std::map<std::string, express::base> get_layers(const express::base&) = 0;
|
||||
virtual std::vector<express::base> find_openings(const express::base&) = 0;
|
||||
virtual void initialize_settings() = 0;
|
||||
virtual bool get_layerset_information(const express::Base&, layerset_information&, int&) = 0;
|
||||
virtual bool get_wall_neighbours(const express::Base&, std::vector<endpoint_connection>&) = 0;
|
||||
virtual const express::Base get_product_type(const express::Base&) = 0;
|
||||
virtual const express::Base get_single_material_association(const express::Base&) = 0;
|
||||
virtual bool get_layerset_information(const express::base&, layerset_information&, int&) = 0;
|
||||
virtual bool get_wall_neighbours(const express::base&, std::vector<endpoint_connection>&) = 0;
|
||||
virtual const express::base get_product_type(const express::base&) = 0;
|
||||
virtual const express::base get_single_material_association(const express::base&) = 0;
|
||||
virtual double get_length_unit() const = 0;
|
||||
virtual const std::string& get_length_unit_name() const = 0;
|
||||
virtual express::Base representation_of(const express::Base& product) = 0;
|
||||
virtual express::base representation_of(const express::base& product) = 0;
|
||||
|
||||
const Settings& settings() const { return settings_; }
|
||||
Settings& settings() { return settings_; }
|
||||
const ifcopenshell::geom::settings& settings() const { return settings_; }
|
||||
ifcopenshell::geom::settings& settings() { return settings_; }
|
||||
::logger& logger() const { return logger_; }
|
||||
|
||||
bool use_caching() const { return use_caching_; }
|
||||
@@ -80,12 +80,12 @@ namespace geometry {
|
||||
};
|
||||
|
||||
namespace impl {
|
||||
typedef boost::function3<abstract_mapping*, ifcopenshell::file*, Settings&, ::logger&> mapping_fn;
|
||||
typedef boost::function3<abstract_mapping*, ifcopenshell::file*, ifcopenshell::geom::settings&, ::logger&> mapping_fn;
|
||||
|
||||
class IFC_GEOM_API mapping_registry {
|
||||
public:
|
||||
void bind(const std::string& schema_name, mapping_fn fn, const ifcopenshell::plugin::module& module = ifcopenshell::plugin::module());
|
||||
abstract_mapping* construct(ifcopenshell::file* file, Settings& settings, ::logger& logger = ::logger::root());
|
||||
abstract_mapping* construct(ifcopenshell::file* file, ifcopenshell::geom::settings& settings, ::logger& logger = ::logger::root());
|
||||
|
||||
private:
|
||||
struct entry {
|
||||
@@ -98,14 +98,14 @@ namespace geometry {
|
||||
|
||||
IFC_GEOM_API mapping_registry& mapping_registry_instance();
|
||||
|
||||
class IFC_GEOM_API MappingFactoryImplementation {
|
||||
class IFC_GEOM_API mapping_factory_implementation {
|
||||
public:
|
||||
MappingFactoryImplementation();
|
||||
mapping_factory_implementation();
|
||||
void bind(const std::string& schema_name, mapping_fn);
|
||||
abstract_mapping* construct(ifcopenshell::file*, Settings&, ::logger& logger = ::logger::root());
|
||||
abstract_mapping* construct(ifcopenshell::file*, ifcopenshell::geom::settings&, ::logger& logger = ::logger::root());
|
||||
};
|
||||
|
||||
IFC_GEOM_API MappingFactoryImplementation& mapping_implementations();
|
||||
IFC_GEOM_API mapping_factory_implementation& mapping_implementations();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
|
||||
#include <boost/math/quadrature/trapezoidal.hpp>
|
||||
|
||||
using namespace ifcopenshell::geometry;
|
||||
using namespace ifcopenshell::geom;
|
||||
|
||||
std::vector<double> ifcopenshell::geometry::helmert_curve_point(double A0, double A1, double A2, double s) {
|
||||
std::vector<double> ifcopenshell::geom::helmert_curve_point(double A0, double A1, double A2, double s) {
|
||||
auto theta = [A0, A1, A2](double t) -> double {
|
||||
auto a0 = A0 ? t / A0 : 0.0;
|
||||
auto a1 = A1 ? A1 * std::pow(t, 2) / (2 * fabs(std::pow(A1, 3))) : 0.0;
|
||||
@@ -22,7 +22,7 @@ std::vector<double> ifcopenshell::geometry::helmert_curve_point(double A0, doubl
|
||||
}
|
||||
|
||||
struct functor_fn_evaluator : public fn_evaluator {
|
||||
functor_fn_evaluator(taxonomy::functor_item::const_ptr fn, const ifcopenshell::geometry::Settings& settings) : fn_evaluator(settings),
|
||||
functor_fn_evaluator(taxonomy::functor_item::const_ptr fn, const ifcopenshell::geom::settings& settings) : fn_evaluator(settings),
|
||||
fn_(fn) {
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ struct functor_fn_evaluator : public fn_evaluator {
|
||||
};
|
||||
|
||||
struct piecewise_fn_evaluator : public fn_evaluator {
|
||||
piecewise_fn_evaluator(taxonomy::piecewise_function::const_ptr fn, const ifcopenshell::geometry::Settings& settings) : fn_evaluator(settings),
|
||||
piecewise_fn_evaluator(taxonomy::piecewise_function::const_ptr fn, const ifcopenshell::geom::settings& settings) : fn_evaluator(settings),
|
||||
fn_(fn) {
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ struct piecewise_fn_evaluator : public fn_evaluator {
|
||||
double span_start = s;
|
||||
for (auto& fn : fn_->spans()) {
|
||||
double span_end = span_start + fn->length();
|
||||
auto tolerance = settings_.get<ifcopenshell::geometry::settings::Precision>().get();
|
||||
auto tolerance = settings_.get<ifcopenshell::geom::settings::Precision>().get();
|
||||
if (span_start <= u && u < span_end + tolerance) {
|
||||
return {span_start, span_end, fn};
|
||||
}
|
||||
@@ -87,7 +87,7 @@ struct piecewise_fn_evaluator : public fn_evaluator {
|
||||
};
|
||||
|
||||
struct gradient_fn_evaluator : public fn_evaluator {
|
||||
gradient_fn_evaluator(taxonomy::gradient_function::const_ptr fn, const ifcopenshell::geometry::Settings& settings) :
|
||||
gradient_fn_evaluator(taxonomy::gradient_function::const_ptr fn, const ifcopenshell::geom::settings& settings) :
|
||||
fn_evaluator(settings),
|
||||
fn_(fn),
|
||||
horizontal_evaluator_(settings, fn->get_horizontal()),
|
||||
@@ -120,7 +120,7 @@ struct gradient_fn_evaluator : public fn_evaluator {
|
||||
};
|
||||
|
||||
struct cant_fn_evaluator : public fn_evaluator {
|
||||
cant_fn_evaluator(taxonomy::cant_function::const_ptr fn, const ifcopenshell::geometry::Settings& settings) : fn_evaluator(settings),
|
||||
cant_fn_evaluator(taxonomy::cant_function::const_ptr fn, const ifcopenshell::geom::settings& settings) : fn_evaluator(settings),
|
||||
fn_(fn),
|
||||
gradient_evaluator_(settings, fn->get_gradient()),
|
||||
cant_evaluator_(settings, fn->get_cant()) {
|
||||
@@ -184,7 +184,7 @@ struct cant_fn_evaluator : public fn_evaluator {
|
||||
};
|
||||
|
||||
struct offset_fn_evaluator : public fn_evaluator {
|
||||
offset_fn_evaluator(taxonomy::offset_function::const_ptr fn, const ifcopenshell::geometry::Settings& settings) : fn_evaluator(settings),
|
||||
offset_fn_evaluator(taxonomy::offset_function::const_ptr fn, const ifcopenshell::geom::settings& settings) : fn_evaluator(settings),
|
||||
fn_(fn),
|
||||
basis_evaluator_(settings, fn->get_basis()),
|
||||
offset_evaluator_(settings, fn->get_offset()) {
|
||||
@@ -208,7 +208,7 @@ struct offset_fn_evaluator : public fn_evaluator {
|
||||
|
||||
|
||||
|
||||
function_item_evaluator::function_item_evaluator(const ifcopenshell::geometry::Settings& settings,taxonomy::function_item::const_ptr fn, logger& logger) : logger_(logger) {
|
||||
function_item_evaluator::function_item_evaluator(const ifcopenshell::geom::settings& settings,taxonomy::function_item::const_ptr fn, logger& logger) : logger_(logger) {
|
||||
auto kind = fn ? fn->kind() : taxonomy::kinds::NODE;
|
||||
if (kind == taxonomy::FUNCTOR_ITEM) {
|
||||
fn_evaluator_ = new functor_fn_evaluator(std::dynamic_pointer_cast<const taxonomy::functor_item>(fn),settings);
|
||||
@@ -238,10 +238,10 @@ std::vector<double> function_item_evaluator::evaluation_points() const {
|
||||
if (!eval_points_.has_value()) {
|
||||
double curve_length = fn_evaluator_->length();
|
||||
|
||||
auto param_type = fn_evaluator_->settings_.get<ifcopenshell::geometry::settings::FunctionStepType>().get();
|
||||
auto param = fn_evaluator_->settings_.get<ifcopenshell::geometry::settings::FunctionStepParam>().get();
|
||||
auto param_type = fn_evaluator_->settings_.get<ifcopenshell::geom::settings::FunctionStepType>().get();
|
||||
auto param = fn_evaluator_->settings_.get<ifcopenshell::geom::settings::FunctionStepParam>().get();
|
||||
unsigned num_steps = 0;
|
||||
if (param_type == ifcopenshell::geometry::settings::FunctionStepMethod::MAXSTEPSIZE) {
|
||||
if (param_type == ifcopenshell::geom::settings::FunctionStepMethod::MAXSTEPSIZE) {
|
||||
// parameter is max step size
|
||||
num_steps = (unsigned)std::ceil(curve_length / param);
|
||||
} else {
|
||||
@@ -298,7 +298,7 @@ Eigen::Matrix4d function_item_evaluator::evaluate(double u) const {
|
||||
throw std::runtime_error("Function item not initialized");
|
||||
}
|
||||
Eigen::Matrix4d m = fn_evaluator_->evaluate(u);
|
||||
if (!fn_evaluator_->settings_.get<ifcopenshell::geometry::settings::ComputeCurvature>().get()) {
|
||||
if (!fn_evaluator_->settings_.get<ifcopenshell::geom::settings::ComputeCurvature>().get()) {
|
||||
m.row(3) = Eigen::Vector4d(0, 0, 0, 1);
|
||||
}
|
||||
return m;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#include <boost/function.hpp>
|
||||
|
||||
namespace ifcopenshell { namespace geometry {
|
||||
namespace ifcopenshell { namespace geom {
|
||||
|
||||
/// @brief Computes a point on a helmert curve at s.
|
||||
/// Returns (x,y,theta) at L/2. The results are in a vector so they can be returned to python
|
||||
@@ -18,12 +18,12 @@ IFC_GEOM_API std::vector<double> helmert_curve_point(double A0, double A1, doubl
|
||||
/// @param loop
|
||||
/// @return
|
||||
static taxonomy::function_item::ptr convert_loop_to_function_item(taxonomy::loop::ptr loop) {
|
||||
return ifcopenshell::geometry::taxonomy::dcast<taxonomy::function_item>(loop);
|
||||
return ifcopenshell::geom::taxonomy::dcast<taxonomy::function_item>(loop);
|
||||
}
|
||||
|
||||
/// @brief Abstract class for evaluating a function_item. This class is specialized for each of the function_item types.
|
||||
struct IFC_GEOM_API fn_evaluator {
|
||||
fn_evaluator(const ifcopenshell::geometry::Settings& settings, logger& logger = ::logger::root()) : settings_(settings), logger_(logger) {
|
||||
fn_evaluator(const ifcopenshell::geom::settings& settings, logger& logger = ::logger::root()) : settings_(settings), logger_(logger) {
|
||||
}
|
||||
fn_evaluator(const fn_evaluator& other) = default;
|
||||
virtual ~fn_evaluator() = default;
|
||||
@@ -35,7 +35,7 @@ struct IFC_GEOM_API fn_evaluator {
|
||||
virtual double end() const = 0;
|
||||
double length() const { return end() - start(); }
|
||||
|
||||
ifcopenshell::geometry::Settings settings_;
|
||||
ifcopenshell::geom::settings settings_;
|
||||
|
||||
protected:
|
||||
logger& logger_;
|
||||
@@ -44,7 +44,7 @@ struct IFC_GEOM_API fn_evaluator {
|
||||
/// @brief utility class to evaluate function_item objects.
|
||||
class IFC_GEOM_API function_item_evaluator {
|
||||
public:
|
||||
function_item_evaluator(const ifcopenshell::geometry::Settings& settings, taxonomy::function_item::const_ptr fn, logger& logger = ::logger::root());
|
||||
function_item_evaluator(const ifcopenshell::geom::settings& settings, taxonomy::function_item::const_ptr fn, logger& logger = ::logger::root());
|
||||
function_item_evaluator(const function_item_evaluator& other);
|
||||
~function_item_evaluator();
|
||||
|
||||
@@ -85,4 +85,4 @@ class IFC_GEOM_API function_item_evaluator {
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+15
-15
@@ -24,18 +24,18 @@
|
||||
#include "kernel_registry.h"
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace geometry {
|
||||
namespace geom {
|
||||
namespace kernels {
|
||||
|
||||
class HybridKernel : public ifcopenshell::geometry::kernels::AbstractKernel {
|
||||
std::vector<std::unique_ptr<AbstractKernel>> kernels_;
|
||||
ifcopenshell::geometry::abstract_mapping* mapping_;
|
||||
class hybrid_kernel : public ifcopenshell::geom::kernels::abstract_kernel {
|
||||
std::vector<std::unique_ptr<abstract_kernel>> kernels_;
|
||||
ifcopenshell::geom::abstract_mapping* mapping_;
|
||||
ifcopenshell::file* file_;
|
||||
public:
|
||||
HybridKernel(const std::string& name, ifcopenshell::file* file, Settings& settings, std::vector<std::unique_ptr<AbstractKernel>>&& kernels, ::logger& logger = ::logger::root())
|
||||
: AbstractKernel(name, settings, logger)
|
||||
hybrid_kernel(const std::string& name, ifcopenshell::file* file, ifcopenshell::geom::settings& settings, std::vector<std::unique_ptr<abstract_kernel>>&& kernels, ::logger& logger = ::logger::root())
|
||||
: abstract_kernel(name, settings, logger)
|
||||
, kernels_(std::move(kernels))
|
||||
, mapping_(ifcopenshell::geometry::impl::mapping_implementations().construct(file, settings, logger))
|
||||
, mapping_(ifcopenshell::geom::impl::mapping_implementations().construct(file, settings, logger))
|
||||
, file_(file)
|
||||
{
|
||||
}
|
||||
@@ -48,7 +48,7 @@ namespace ifcopenshell {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
virtual bool convert(const taxonomy::ptr item, IfcGeom::ConversionResults& rs)
|
||||
virtual bool convert(const taxonomy::ptr item, ifcopenshell::geom::conversion_results& rs)
|
||||
{
|
||||
auto ops = mapping_->find_openings(item->instance);
|
||||
bool has_openings = ops.size();
|
||||
@@ -77,7 +77,7 @@ namespace ifcopenshell {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
virtual bool apply_layerset(IfcGeom::ConversionResults& items, const ifcopenshell::geometry::layerset_information& layers)
|
||||
virtual bool apply_layerset(ifcopenshell::geom::conversion_results& items, const ifcopenshell::geom::layerset_information& layers)
|
||||
{
|
||||
for (auto& k : kernels_) {
|
||||
bool success = false;
|
||||
@@ -90,7 +90,7 @@ namespace ifcopenshell {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
virtual bool apply_folded_layerset(IfcGeom::ConversionResults& items, const ifcopenshell::geometry::layerset_information& layers, const std::map<express::Base, ifcopenshell::geometry::layerset_information>& folds)
|
||||
virtual bool apply_folded_layerset(ifcopenshell::geom::conversion_results& items, const ifcopenshell::geom::layerset_information& layers, const std::map<express::base, ifcopenshell::geom::layerset_information>& folds)
|
||||
{
|
||||
for (auto& k : kernels_) {
|
||||
bool success = false;
|
||||
@@ -103,8 +103,8 @@ namespace ifcopenshell {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
virtual bool convert_openings(const express::Base& entity, const std::vector<std::pair<taxonomy::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
|
||||
const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes)
|
||||
virtual bool convert_openings(const express::base& entity, const std::vector<std::pair<taxonomy::ptr, ifcopenshell::geom::taxonomy::matrix4>>& openings,
|
||||
const ifcopenshell::geom::conversion_results& entity_shapes, const ifcopenshell::geom::taxonomy::matrix4& entity_trsf, ifcopenshell::geom::conversion_results& cut_shapes)
|
||||
{
|
||||
for (auto& k : kernels_) {
|
||||
bool is_valid = true;
|
||||
@@ -127,14 +127,14 @@ namespace ifcopenshell {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
virtual AbstractKernel* clone(::logger& logger) const
|
||||
virtual abstract_kernel* clone(::logger& logger) const
|
||||
{
|
||||
std::vector<std::unique_ptr<AbstractKernel>> ks;
|
||||
std::vector<std::unique_ptr<abstract_kernel>> ks;
|
||||
for (auto& k : kernels_) {
|
||||
ks.emplace_back(k->clone(logger));
|
||||
}
|
||||
// @todo ugly
|
||||
return new HybridKernel(geometry_library(), file_, const_cast<Settings&>(settings()), std::move(ks), logger);
|
||||
return new hybrid_kernel(geometry_library(), file_, const_cast<ifcopenshell::geom::settings&>(settings()), std::move(ks), logger);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include <boost/range/combine.hpp>
|
||||
|
||||
using namespace ifcopenshell::geometry;
|
||||
using namespace ifcopenshell::geom;
|
||||
|
||||
namespace {
|
||||
// std::lerp when upgrading to C++ 20
|
||||
@@ -35,7 +35,7 @@ bool has_intersection(const std::set<T, Cmp>& A,
|
||||
|
||||
}
|
||||
|
||||
taxonomy::loft::ptr ifcopenshell::geometry::make_loft(const Settings& settings_, const express::Base inst, const taxonomy::function_item::ptr& fn, std::vector<cross_section>& cross_sections, logger& logger)
|
||||
taxonomy::loft::ptr ifcopenshell::geom::make_loft(const ifcopenshell::geom::settings& settings, const express::base inst, const taxonomy::function_item::ptr& fn, std::vector<cross_section>& cross_sections, logger& logger)
|
||||
{
|
||||
std::sort(cross_sections.begin(), cross_sections.end());
|
||||
|
||||
@@ -46,7 +46,7 @@ taxonomy::loft::ptr ifcopenshell::geometry::make_loft(const Settings& settings_,
|
||||
// @todo currently only the case is handled where directrix returns a function_item
|
||||
// @todo this "if" statement is not really required because the function returns at the start if the Directrix is not a function_item function
|
||||
if (fn) {
|
||||
function_item_evaluator evaluator(settings_, fn);
|
||||
function_item_evaluator evaluator(settings, fn);
|
||||
double start = std::max(0., cross_sections.front().dist_along);
|
||||
double end = std::min(fn->length(), cross_sections.back().dist_along);
|
||||
|
||||
@@ -56,10 +56,10 @@ taxonomy::loft::ptr ifcopenshell::geometry::make_loft(const Settings& settings_,
|
||||
}
|
||||
|
||||
auto curve_length = end - start;
|
||||
auto param_type = settings_.get<ifcopenshell::geometry::settings::FunctionStepType>().get();
|
||||
auto param = settings_.get<ifcopenshell::geometry::settings::FunctionStepParam>().get();
|
||||
auto param_type = settings.get<ifcopenshell::geom::settings::FunctionStepType>().get();
|
||||
auto param = settings.get<ifcopenshell::geom::settings::FunctionStepParam>().get();
|
||||
size_t num_steps = 0;
|
||||
if (param_type == ifcopenshell::geometry::settings::FunctionStepMethod::MAXSTEPSIZE) {
|
||||
if (param_type == ifcopenshell::geom::settings::FunctionStepMethod::MAXSTEPSIZE) {
|
||||
// parameter is max step size
|
||||
num_steps = (size_t)std::ceil(curve_length / param);
|
||||
} else {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
namespace ifcopenshell {
|
||||
|
||||
namespace geometry {
|
||||
namespace geom {
|
||||
|
||||
struct IFC_GEOM_API cross_section {
|
||||
double dist_along;
|
||||
@@ -21,9 +21,9 @@ namespace ifcopenshell {
|
||||
}
|
||||
};
|
||||
|
||||
IFC_GEOM_API taxonomy::loft::ptr make_loft(const Settings& settings_, const express::Base inst, const taxonomy::function_item::ptr& directrix, std::vector<cross_section>& cross_sections, logger& logger = ::logger::root());
|
||||
IFC_GEOM_API taxonomy::loft::ptr make_loft(const ifcopenshell::geom::settings& settings, const express::base inst, const taxonomy::function_item::ptr& directrix, std::vector<cross_section>& cross_sections, logger& logger = ::logger::root());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -40,22 +40,22 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
const char* ifcopenshell::geometry::kernels::kernel_plugin_registration_symbol() {
|
||||
const char* ifcopenshell::geom::kernels::kernel_plugin_registration_symbol() {
|
||||
return "ifcopenshell_register_kernel_plugin_v1";
|
||||
}
|
||||
|
||||
ifcopenshell::plugin::metadata ifcopenshell::geometry::kernels::kernel_plugin_metadata(const std::string& plugin_name) {
|
||||
ifcopenshell::plugin::metadata ifcopenshell::geom::kernels::kernel_plugin_metadata(const std::string& plugin_name) {
|
||||
plugin::metadata metadata;
|
||||
metadata.kind_ = plugin::kind::kernel;
|
||||
metadata.id = kernel_plugin_prefix + plugin_name;
|
||||
return metadata;
|
||||
}
|
||||
|
||||
std::filesystem::path ifcopenshell::geometry::kernels::kernel_plugin_directory() {
|
||||
return plugin::module_directory(reinterpret_cast<const void*>(&ifcopenshell::geometry::kernels::load_kernel_plugins));
|
||||
std::filesystem::path ifcopenshell::geom::kernels::kernel_plugin_directory() {
|
||||
return plugin::module_directory(reinterpret_cast<const void*>(&ifcopenshell::geom::kernels::load_kernel_plugins));
|
||||
}
|
||||
|
||||
void ifcopenshell::geometry::kernels::load_kernel_plugins(kernel_registry& registry) {
|
||||
void ifcopenshell::geom::kernels::load_kernel_plugins(kernel_registry& registry) {
|
||||
plugin::manager manager;
|
||||
plugin::add_search_paths_or_default(manager, &kernel_plugin_directory);
|
||||
|
||||
@@ -70,7 +70,7 @@ void ifcopenshell::geometry::kernels::load_kernel_plugins(kernel_registry& regis
|
||||
}
|
||||
}
|
||||
|
||||
bool ifcopenshell::geometry::kernels::load_kernel_plugin(kernel_registry& registry, const std::string& backend_id) {
|
||||
bool ifcopenshell::geom::kernels::load_kernel_plugin(kernel_registry& registry, const std::string& backend_id) {
|
||||
plugin::manager manager;
|
||||
plugin::add_search_paths_or_default(manager, &kernel_plugin_directory);
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <filesystem>
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace geometry {
|
||||
namespace geom {
|
||||
namespace kernels {
|
||||
|
||||
typedef void register_kernel_plugin_fn(kernel_registry&, const ifcopenshell::plugin::module&);
|
||||
|
||||
@@ -47,9 +47,9 @@ namespace {
|
||||
return !prefix.empty() && text.rfind(prefix, 0) == 0;
|
||||
}
|
||||
|
||||
void register_kernel_module(ifcopenshell::geometry::kernels::kernel_registry& registry, const ifcopenshell::plugin::module& module) {
|
||||
auto register_plugin = module.get_alias<ifcopenshell::geometry::kernels::register_kernel_plugin_fn>(
|
||||
ifcopenshell::geometry::kernels::kernel_plugin_registration_symbol());
|
||||
void register_kernel_module(ifcopenshell::geom::kernels::kernel_registry& registry, const ifcopenshell::plugin::module& module) {
|
||||
auto register_plugin = module.get_alias<ifcopenshell::geom::kernels::register_kernel_plugin_fn>(
|
||||
ifcopenshell::geom::kernels::kernel_plugin_registration_symbol());
|
||||
register_plugin(registry, module);
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace {
|
||||
bool has_module = false;
|
||||
};
|
||||
|
||||
void consider_kernel_info(kernel_match& match, const std::string& geometry_library_lower, const ifcopenshell::geometry::kernels::kernel_info& info) {
|
||||
void consider_kernel_info(kernel_match& match, const std::string& geometry_library_lower, const ifcopenshell::geom::kernels::kernel_info& info) {
|
||||
const auto backend_id = kernel_key(info.backend_id);
|
||||
if (is_prefix(geometry_library_lower, backend_id) && backend_id.size() > match.backend_id.size()) {
|
||||
match.backend_id = backend_id;
|
||||
@@ -67,7 +67,7 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
kernel_match find_kernel_match(ifcopenshell::geometry::kernels::kernel_registry& registry, const std::string& geometry_library_lower) {
|
||||
kernel_match find_kernel_match(ifcopenshell::geom::kernels::kernel_registry& registry, const std::string& geometry_library_lower) {
|
||||
kernel_match match;
|
||||
|
||||
for (const auto& info : registry.kernels()) {
|
||||
@@ -75,7 +75,7 @@ namespace {
|
||||
}
|
||||
|
||||
ifcopenshell::plugin::manager manager;
|
||||
ifcopenshell::plugin::add_search_paths_or_default(manager, &ifcopenshell::geometry::kernels::kernel_plugin_directory);
|
||||
ifcopenshell::plugin::add_search_paths_or_default(manager, &ifcopenshell::geom::kernels::kernel_plugin_directory);
|
||||
for (const auto& path : manager.discover(kernel_plugin_prefix)) {
|
||||
ifcopenshell::plugin::module module;
|
||||
try {
|
||||
@@ -92,7 +92,7 @@ namespace {
|
||||
continue;
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::kernels::kernel_registry plugin_registry;
|
||||
ifcopenshell::geom::kernels::kernel_registry plugin_registry;
|
||||
register_kernel_module(plugin_registry, module);
|
||||
for (const auto& info : plugin_registry.kernels()) {
|
||||
const auto backend_id = kernel_key(info.backend_id);
|
||||
@@ -112,7 +112,7 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
void ifcopenshell::geometry::kernels::kernel_registry::bind(const kernel_info& info, create_fn create, const plugin::module& module) {
|
||||
void ifcopenshell::geom::kernels::kernel_registry::bind(const kernel_info& info, create_fn create, const plugin::module& module) {
|
||||
entry entry;
|
||||
entry.info_ = info;
|
||||
entry.create_ = create;
|
||||
@@ -120,19 +120,19 @@ void ifcopenshell::geometry::kernels::kernel_registry::bind(const kernel_info& i
|
||||
entries_[kernel_key(info.backend_id)] = entry;
|
||||
}
|
||||
|
||||
bool ifcopenshell::geometry::kernels::kernel_registry::has(const std::string& backend_id) const {
|
||||
bool ifcopenshell::geom::kernels::kernel_registry::has(const std::string& backend_id) const {
|
||||
return entries_.find(kernel_key(backend_id)) != entries_.end();
|
||||
}
|
||||
|
||||
std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel> ifcopenshell::geometry::kernels::kernel_registry::create(const std::string& backend_id, ifcopenshell::file* file, Settings& settings) const {
|
||||
std::unique_ptr<ifcopenshell::geom::kernels::abstract_kernel> ifcopenshell::geom::kernels::kernel_registry::create(const std::string& backend_id, ifcopenshell::file* file, ifcopenshell::geom::settings& settings) const {
|
||||
const auto iter = entries_.find(kernel_key(backend_id));
|
||||
if (iter == entries_.end()) {
|
||||
throw ifcopenshell::exception("No geometry kernel registered for " + backend_id);
|
||||
}
|
||||
return std::unique_ptr<AbstractKernel>(iter->second.create_(file, settings));
|
||||
return std::unique_ptr<abstract_kernel>(iter->second.create_(file, settings));
|
||||
}
|
||||
|
||||
std::vector<ifcopenshell::geometry::kernels::kernel_info> ifcopenshell::geometry::kernels::kernel_registry::kernels() const {
|
||||
std::vector<ifcopenshell::geom::kernels::kernel_info> ifcopenshell::geom::kernels::kernel_registry::kernels() const {
|
||||
std::vector<kernel_info> result;
|
||||
for (const auto& pair : entries_) {
|
||||
result.push_back(pair.second.info_);
|
||||
@@ -140,12 +140,12 @@ std::vector<ifcopenshell::geometry::kernels::kernel_info> ifcopenshell::geometry
|
||||
return result;
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::kernels::kernel_registry& ifcopenshell::geometry::kernels::kernel_registry_instance() {
|
||||
ifcopenshell::geom::kernels::kernel_registry& ifcopenshell::geom::kernels::kernel_registry_instance() {
|
||||
static kernel_registry registry;
|
||||
return registry;
|
||||
}
|
||||
|
||||
std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel> ifcopenshell::geometry::kernels::construct(ifcopenshell::file* file, const std::string& geometry_library, Settings& settings) {
|
||||
std::unique_ptr<ifcopenshell::geom::kernels::abstract_kernel> ifcopenshell::geom::kernels::construct(ifcopenshell::file* file, const std::string& geometry_library, ifcopenshell::geom::settings& settings) {
|
||||
auto geometry_library_lower = boost::to_lower_copy(geometry_library);
|
||||
auto& registry = kernel_registry_instance();
|
||||
|
||||
@@ -158,7 +158,7 @@ std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel> ifcopenshell::g
|
||||
|
||||
if (geometry_library_lower.rfind("hybrid-", 0) == 0) {
|
||||
geometry_library_lower = geometry_library_lower.substr(strlen("hybrid"));
|
||||
std::vector<std::unique_ptr<AbstractKernel>> kernels;
|
||||
std::vector<std::unique_ptr<abstract_kernel>> kernels;
|
||||
while (!geometry_library_lower.empty()) {
|
||||
if (geometry_library_lower.find("-", 0) == 0) {
|
||||
geometry_library_lower = geometry_library_lower.substr(strlen("-"));
|
||||
@@ -183,7 +183,7 @@ std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel> ifcopenshell::g
|
||||
}
|
||||
|
||||
if (!kernels.empty()) {
|
||||
return std::make_unique<HybridKernel>(geometry_library, file, settings, std::move(kernels));
|
||||
return std::make_unique<hybrid_kernel>(geometry_library, file, settings, std::move(kernels));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
namespace ifcopenshell {
|
||||
class file;
|
||||
|
||||
namespace geometry {
|
||||
namespace geom {
|
||||
namespace kernels {
|
||||
|
||||
struct IFC_GEOM_API kernel_info {
|
||||
@@ -43,11 +43,11 @@ namespace ifcopenshell {
|
||||
|
||||
class IFC_GEOM_API kernel_registry {
|
||||
public:
|
||||
typedef boost::function2<AbstractKernel*, ifcopenshell::file*, Settings&> create_fn;
|
||||
typedef boost::function2<abstract_kernel*, ifcopenshell::file*, ifcopenshell::geom::settings&> create_fn;
|
||||
|
||||
void bind(const kernel_info& info, create_fn create, const ifcopenshell::plugin::module& module = ifcopenshell::plugin::module());
|
||||
bool has(const std::string& backend_id) const;
|
||||
std::unique_ptr<AbstractKernel> create(const std::string& backend_id, ifcopenshell::file* file, Settings& settings) const;
|
||||
std::unique_ptr<abstract_kernel> create(const std::string& backend_id, ifcopenshell::file* file, ifcopenshell::geom::settings& settings) const;
|
||||
std::vector<kernel_info> kernels() const;
|
||||
|
||||
private:
|
||||
@@ -61,7 +61,7 @@ namespace ifcopenshell {
|
||||
};
|
||||
|
||||
IFC_GEOM_API kernel_registry& kernel_registry_instance();
|
||||
IFC_GEOM_API std::unique_ptr<AbstractKernel> construct(ifcopenshell::file* file, const std::string& geometry_library, Settings& settings);
|
||||
IFC_GEOM_API std::unique_ptr<abstract_kernel> construct(ifcopenshell::file* file, const std::string& geometry_library, ifcopenshell::geom::settings& settings);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -45,8 +45,8 @@
|
||||
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#define Kernel_ SimpleKernel_
|
||||
#define CgalShape SimpleCgalShape
|
||||
#define kernel_ Simplekernel_
|
||||
#define cgal_shape SimpleCgalShape
|
||||
#define cgal_placement_t cgal_simple_placement_t
|
||||
#define cgal_point_t cgal_simple_point_t
|
||||
#define cgal_direction_t cgal_simple_direction_t
|
||||
@@ -59,23 +59,23 @@
|
||||
#define cgal_vertex_descriptor_t cgal_simple_vertex_descriptor_t
|
||||
#define cgal_face_descriptor_t cgal_simple_face_descriptor_t
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel_;
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel kernel_;
|
||||
|
||||
#else
|
||||
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
#include <CGAL/Nef_polyhedron_3.h>
|
||||
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel_;
|
||||
typedef CGAL::Exact_predicates_exact_constructions_kernel kernel_;
|
||||
|
||||
#endif
|
||||
|
||||
typedef Kernel_::Aff_transformation_3 cgal_placement_t;
|
||||
typedef Kernel_::Point_3 cgal_point_t;
|
||||
typedef Kernel_::Vector_3 cgal_direction_t;
|
||||
typedef Kernel_::Vector_3 cgal_vector_t;
|
||||
typedef Kernel_::Plane_3 cgal_plane_t;
|
||||
typedef std::vector<Kernel_::Point_3> cgal_curve_t;
|
||||
typedef std::vector<Kernel_::Point_3> cgal_wire_t;
|
||||
typedef kernel_::Aff_transformation_3 cgal_placement_t;
|
||||
typedef kernel_::Point_3 cgal_point_t;
|
||||
typedef kernel_::Vector_3 cgal_direction_t;
|
||||
typedef kernel_::Vector_3 cgal_vector_t;
|
||||
typedef kernel_::Plane_3 cgal_plane_t;
|
||||
typedef std::vector<kernel_::Point_3> cgal_curve_t;
|
||||
typedef std::vector<kernel_::Point_3> cgal_wire_t;
|
||||
|
||||
namespace {
|
||||
struct cgal_face_t {
|
||||
@@ -84,28 +84,28 @@ namespace {
|
||||
};
|
||||
}
|
||||
|
||||
typedef CGAL::Polyhedron_3<Kernel_> cgal_shape_t;
|
||||
typedef boost::graph_traits<CGAL::Polyhedron_3<Kernel_>>::vertex_descriptor cgal_vertex_descriptor_t;
|
||||
typedef boost::graph_traits<CGAL::Polyhedron_3<Kernel_>>::face_descriptor cgal_face_descriptor_t;
|
||||
typedef CGAL::Polyhedron_3<kernel_> cgal_shape_t;
|
||||
typedef boost::graph_traits<CGAL::Polyhedron_3<kernel_>>::vertex_descriptor cgal_vertex_descriptor_t;
|
||||
typedef boost::graph_traits<CGAL::Polyhedron_3<kernel_>>::face_descriptor cgal_face_descriptor_t;
|
||||
|
||||
#include "../../../ifcgeom/ConversionResult.h"
|
||||
|
||||
namespace ifcopenshell { namespace geometry {
|
||||
namespace ifcopenshell { namespace geom {
|
||||
|
||||
using IfcGeom::OpaqueCoordinate;
|
||||
using IfcGeom::OpaqueNumber;
|
||||
using ifcopenshell::geom::opaque_coordinate;
|
||||
using ifcopenshell::geom::opaque_number;
|
||||
|
||||
#ifndef IFOPSH_SIMPLE_KERNEL
|
||||
class IFC_GEOMLIBRARY_API NumberEpeck : public OpaqueNumber {
|
||||
class IFC_GEOMLIBRARY_API number_epeck : public opaque_number {
|
||||
private:
|
||||
struct Model : OpaqueNumber::NumberConcept {
|
||||
struct model : opaque_number::number_concept {
|
||||
CGAL::Epeck::FT value;
|
||||
|
||||
Model(const CGAL::Epeck::FT& v)
|
||||
model(const CGAL::Epeck::FT& v)
|
||||
: value(v) {}
|
||||
|
||||
static const Model& as_same(const NumberConcept& other) {
|
||||
auto same = dynamic_cast<const Model*>(&other);
|
||||
static const model& as_same(const number_concept& other) {
|
||||
auto same = dynamic_cast<const model*>(&other);
|
||||
if (same == nullptr) {
|
||||
throw std::runtime_error("Incompatible opaque number types");
|
||||
}
|
||||
@@ -122,39 +122,39 @@ namespace ifcopenshell { namespace geometry {
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<const NumberConcept> add(const NumberConcept& other) const {
|
||||
return std::make_shared<Model>(value + as_same(other).value);
|
||||
virtual std::shared_ptr<const number_concept> add(const number_concept& other) const {
|
||||
return std::make_shared<model>(value + as_same(other).value);
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<const NumberConcept> subtract(const NumberConcept& other) const {
|
||||
return std::make_shared<Model>(value - as_same(other).value);
|
||||
virtual std::shared_ptr<const number_concept> subtract(const number_concept& other) const {
|
||||
return std::make_shared<model>(value - as_same(other).value);
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<const NumberConcept> multiply(const NumberConcept& other) const {
|
||||
return std::make_shared<Model>(value * as_same(other).value);
|
||||
virtual std::shared_ptr<const number_concept> multiply(const number_concept& other) const {
|
||||
return std::make_shared<model>(value * as_same(other).value);
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<const NumberConcept> divide(const NumberConcept& other) const {
|
||||
return std::make_shared<Model>(value / as_same(other).value);
|
||||
virtual std::shared_ptr<const number_concept> divide(const number_concept& other) const {
|
||||
return std::make_shared<model>(value / as_same(other).value);
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<const NumberConcept> negate() const {
|
||||
return std::make_shared<Model>(-value);
|
||||
virtual std::shared_ptr<const number_concept> negate() const {
|
||||
return std::make_shared<model>(-value);
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<const NumberConcept> from_double(double v) const {
|
||||
return std::make_shared<Model>(CGAL::Epeck::FT(v));
|
||||
virtual std::shared_ptr<const number_concept> from_double(double v) const {
|
||||
return std::make_shared<model>(CGAL::Epeck::FT(v));
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<const NumberConcept> from_int(int v) const {
|
||||
return std::make_shared<Model>(CGAL::Epeck::FT(v));
|
||||
virtual std::shared_ptr<const number_concept> from_int(int v) const {
|
||||
return std::make_shared<model>(CGAL::Epeck::FT(v));
|
||||
}
|
||||
|
||||
virtual bool equals(const NumberConcept& other) const {
|
||||
virtual bool equals(const number_concept& other) const {
|
||||
return value == as_same(other).value;
|
||||
}
|
||||
|
||||
virtual bool less_than(const NumberConcept& other) const {
|
||||
virtual bool less_than(const number_concept& other) const {
|
||||
return value < as_same(other).value;
|
||||
}
|
||||
|
||||
@@ -168,8 +168,8 @@ namespace ifcopenshell { namespace geometry {
|
||||
};
|
||||
|
||||
public:
|
||||
NumberEpeck(const CGAL::Epeck::FT& v)
|
||||
: OpaqueNumber(std::make_shared<Model>(v)) {}
|
||||
number_epeck(const CGAL::Epeck::FT& v)
|
||||
: opaque_number(std::make_shared<model>(v)) {}
|
||||
|
||||
const CGAL::Epeck::FT& value() const {
|
||||
return value_as<CGAL::Epeck::FT>();
|
||||
@@ -177,23 +177,23 @@ namespace ifcopenshell { namespace geometry {
|
||||
};
|
||||
#endif
|
||||
|
||||
class IFC_GEOMLIBRARY_API CgalShape : public IfcGeom::ConversionResultShape {
|
||||
class IFC_GEOMLIBRARY_API cgal_shape : public ifcopenshell::geom::conversion_result_shape {
|
||||
private:
|
||||
typedef std::variant<cgal_shape_t, cgal_point_t, cgal_wire_t> cgal_shape_storage_t;
|
||||
|
||||
bool convex_tag_ = false;
|
||||
mutable std::optional<cgal_shape_storage_t> shape_;
|
||||
#ifndef IFOPSH_SIMPLE_KERNEL
|
||||
mutable std::optional<CGAL::Nef_polyhedron_3<Kernel_>> nef_;
|
||||
mutable std::optional<CGAL::Nef_polyhedron_3<kernel_>> nef_;
|
||||
#endif
|
||||
public:
|
||||
|
||||
CgalShape(const cgal_shape_t& shape, bool convex = false, ::logger& logger = ::logger::root());
|
||||
CgalShape(const cgal_point_t& point, bool convex = false);
|
||||
CgalShape(const cgal_wire_t& wire, bool convex = false);
|
||||
cgal_shape(const cgal_shape_t& shape, bool convex = false, ::logger& logger = ::logger::root());
|
||||
cgal_shape(const cgal_point_t& point, bool convex = false);
|
||||
cgal_shape(const cgal_wire_t& wire, bool convex = false);
|
||||
|
||||
#ifndef IFOPSH_SIMPLE_KERNEL
|
||||
CgalShape(const CGAL::Nef_polyhedron_3<Kernel_>& shape, bool convex = false) {
|
||||
cgal_shape(const CGAL::Nef_polyhedron_3<kernel_>& shape, bool convex = false) {
|
||||
nef_ = shape;
|
||||
convex_tag_ = convex;
|
||||
}
|
||||
@@ -204,8 +204,8 @@ namespace ifcopenshell { namespace geometry {
|
||||
|
||||
void to_nef() const;
|
||||
|
||||
operator const CGAL::Nef_polyhedron_3<Kernel_>& () const { to_nef(); return *nef_; }
|
||||
const CGAL::Nef_polyhedron_3<Kernel_>& nef() const { to_nef(); return *nef_; }
|
||||
operator const CGAL::Nef_polyhedron_3<kernel_>& () const { to_nef(); return *nef_; }
|
||||
const CGAL::Nef_polyhedron_3<kernel_>& nef() const { to_nef(); return *nef_; }
|
||||
#else
|
||||
// noop on simple kernel
|
||||
void to_poly() const {}
|
||||
@@ -226,18 +226,18 @@ namespace ifcopenshell { namespace geometry {
|
||||
const cgal_point_t& point() const { return std::get<cgal_point_t>(*shape_); }
|
||||
const cgal_wire_t& wire() const { return std::get<cgal_wire_t>(*shape_); }
|
||||
|
||||
virtual void Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int item_id, int surface_style_id, ::logger& logger = ::logger::root()) const;
|
||||
virtual void Serialize(const ifcopenshell::geometry::taxonomy::matrix4& place, std::string&) const;
|
||||
virtual void Triangulate(ifcopenshell::geom::settings settings, const ifcopenshell::geom::taxonomy::matrix4& place, ifcopenshell::geom::Representation::triangulation* t, int item_id, int surface_style_id, ::logger& logger = ::logger::root()) const;
|
||||
virtual void Serialize(const ifcopenshell::geom::taxonomy::matrix4& place, std::string&) const;
|
||||
|
||||
virtual IfcGeom::ConversionResultShape* clone() const {
|
||||
virtual ifcopenshell::geom::conversion_result_shape* clone() const {
|
||||
if (shape_) {
|
||||
return std::visit([this](const auto& value) -> IfcGeom::ConversionResultShape* {
|
||||
return new CgalShape(value, convex_tag_);
|
||||
return std::visit([this](const auto& value) -> ifcopenshell::geom::conversion_result_shape* {
|
||||
return new cgal_shape(value, convex_tag_);
|
||||
}, *shape_);
|
||||
}
|
||||
#ifndef IFOPSH_SIMPLE_KERNEL
|
||||
if (nef_) {
|
||||
return new CgalShape(*nef_, convex_tag_);
|
||||
return new cgal_shape(*nef_, convex_tag_);
|
||||
}
|
||||
#endif
|
||||
return nullptr;
|
||||
@@ -257,49 +257,49 @@ namespace ifcopenshell { namespace geometry {
|
||||
virtual int num_faces() const;
|
||||
|
||||
// @todo this must be something with a virtual dtor so that we can delete it.
|
||||
virtual std::pair<OpaqueCoordinate<3>, OpaqueCoordinate<3>> bounding_box() const;
|
||||
virtual std::pair<opaque_coordinate<3>, opaque_coordinate<3>> bounding_box() const;
|
||||
|
||||
virtual OpaqueNumber length();
|
||||
virtual OpaqueNumber area();
|
||||
virtual OpaqueNumber volume();
|
||||
virtual opaque_number length();
|
||||
virtual opaque_number area();
|
||||
virtual opaque_number volume();
|
||||
|
||||
virtual OpaqueCoordinate<3> position();
|
||||
virtual OpaqueCoordinate<3> axis();
|
||||
virtual OpaqueCoordinate<4> plane_equation();
|
||||
virtual opaque_coordinate<3> position();
|
||||
virtual opaque_coordinate<3> axis();
|
||||
virtual opaque_coordinate<4> plane_equation();
|
||||
|
||||
virtual std::vector<ConversionResultShape*> convex_decomposition();
|
||||
virtual ConversionResultShape* halfspaces();
|
||||
virtual ConversionResultShape* solid();
|
||||
virtual ConversionResultShape* box();
|
||||
virtual ConversionResultShape* wrap_in_compound();
|
||||
virtual std::vector<conversion_result_shape*> convex_decomposition();
|
||||
virtual conversion_result_shape* halfspaces();
|
||||
virtual conversion_result_shape* solid();
|
||||
virtual conversion_result_shape* box();
|
||||
virtual conversion_result_shape* wrap_in_compound();
|
||||
|
||||
virtual std::vector<ConversionResultShape*> vertices();
|
||||
virtual std::vector<ConversionResultShape*> edges();
|
||||
virtual std::vector<ConversionResultShape*> facets();
|
||||
virtual std::vector<conversion_result_shape*> vertices();
|
||||
virtual std::vector<conversion_result_shape*> edges();
|
||||
virtual std::vector<conversion_result_shape*> facets();
|
||||
|
||||
virtual ConversionResultShape* add(ConversionResultShape*);
|
||||
virtual ConversionResultShape* subtract(ConversionResultShape*);
|
||||
virtual ConversionResultShape* intersect(ConversionResultShape*);
|
||||
virtual ConversionResultShape* concat(ConversionResultShape*);
|
||||
virtual conversion_result_shape* add(conversion_result_shape*);
|
||||
virtual conversion_result_shape* subtract(conversion_result_shape*);
|
||||
virtual conversion_result_shape* intersect(conversion_result_shape*);
|
||||
virtual conversion_result_shape* concat(conversion_result_shape*);
|
||||
|
||||
virtual std::size_t map(OpaqueCoordinate<4>& from, OpaqueCoordinate<4>& to);
|
||||
virtual std::size_t map(const std::vector<OpaqueCoordinate<4>>& from, const std::vector<OpaqueCoordinate<4>>& to);
|
||||
virtual ConversionResultShape* moved(ifcopenshell::geometry::taxonomy::matrix4::ptr) const;
|
||||
virtual std::size_t map(opaque_coordinate<4>& from, opaque_coordinate<4>& to);
|
||||
virtual std::size_t map(const std::vector<opaque_coordinate<4>>& from, const std::vector<opaque_coordinate<4>>& to);
|
||||
virtual conversion_result_shape* moved(ifcopenshell::geom::taxonomy::matrix4::ptr) const;
|
||||
|
||||
virtual bool surface_area_along_direction(double tol, const ifcopenshell::geometry::taxonomy::matrix4::ptr&, double& along_x, double& along_y, double& along_z) const;
|
||||
virtual bool surface_area_along_direction(double tol, const ifcopenshell::geom::taxonomy::matrix4::ptr&, double& along_x, double& along_y, double& along_z) const;
|
||||
|
||||
bool convex_tag() const { return convex_tag_; }
|
||||
bool& convex_tag() { return convex_tag_; }
|
||||
};
|
||||
|
||||
#ifndef IFOPSH_SIMPLE_KERNEL
|
||||
class IFC_GEOMLIBRARY_API CgalShapeHalfSpaceDecomposition : public IfcGeom::ConversionResultShape {
|
||||
class IFC_GEOMLIBRARY_API cgal_shape_half_space_decomposition : public ifcopenshell::geom::conversion_result_shape {
|
||||
private:
|
||||
std::unique_ptr<halfspace_tree<Kernel_>> shape_;
|
||||
std::list<CGAL::Plane_3<Kernel_>> planes_;
|
||||
std::unique_ptr<halfspace_tree<kernel_>> shape_;
|
||||
std::list<CGAL::Plane_3<kernel_>> planes_;
|
||||
|
||||
public:
|
||||
CgalShapeHalfSpaceDecomposition(const CGAL::Nef_polyhedron_3<Kernel_>& shape, bool is_convex) {
|
||||
cgal_shape_half_space_decomposition(const CGAL::Nef_polyhedron_3<kernel_>& shape, bool is_convex) {
|
||||
if (is_convex) {
|
||||
shape_ = std::move(build_halfspace_tree_is_decomposed(shape, planes_));
|
||||
} else {
|
||||
@@ -307,8 +307,8 @@ namespace ifcopenshell { namespace geometry {
|
||||
}
|
||||
}
|
||||
|
||||
CgalShapeHalfSpaceDecomposition(const CGAL::Plane_3<Kernel_>& shape) {
|
||||
shape_.reset(new halfspace_tree_plane<Kernel_>(shape));
|
||||
cgal_shape_half_space_decomposition(const CGAL::Plane_3<kernel_>& shape) {
|
||||
shape_.reset(new halfspace_tree_plane<kernel_>(shape));
|
||||
planes_.push_back(shape);
|
||||
}
|
||||
virtual std::string_view backend_id() const {
|
||||
@@ -319,8 +319,8 @@ namespace ifcopenshell { namespace geometry {
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual void Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int item_id, int surface_style_id, ::logger& logger = ::logger::root()) const;
|
||||
virtual void Serialize(const ifcopenshell::geometry::taxonomy::matrix4& place, std::string&) const;
|
||||
virtual void Triangulate(ifcopenshell::geom::settings settings, const ifcopenshell::geom::taxonomy::matrix4& place, ifcopenshell::geom::Representation::triangulation* t, int item_id, int surface_style_id, ::logger& logger = ::logger::root()) const;
|
||||
virtual void Serialize(const ifcopenshell::geom::taxonomy::matrix4& place, std::string&) const;
|
||||
|
||||
virtual int surface_genus() const;
|
||||
virtual bool is_manifold() const;
|
||||
@@ -332,39 +332,39 @@ namespace ifcopenshell { namespace geometry {
|
||||
virtual double bounding_box(void*&) const;
|
||||
|
||||
// @todo this must be something with a virtual dtor so that we can delete it.
|
||||
virtual std::pair<OpaqueCoordinate<3>, OpaqueCoordinate<3>> bounding_box() const;
|
||||
virtual std::pair<opaque_coordinate<3>, opaque_coordinate<3>> bounding_box() const;
|
||||
virtual void set_box(void* b);
|
||||
|
||||
virtual OpaqueNumber length();
|
||||
virtual OpaqueNumber area();
|
||||
virtual OpaqueNumber volume();
|
||||
virtual opaque_number length();
|
||||
virtual opaque_number area();
|
||||
virtual opaque_number volume();
|
||||
|
||||
virtual OpaqueCoordinate<3> position();
|
||||
virtual OpaqueCoordinate<3> axis();
|
||||
virtual OpaqueCoordinate<4> plane_equation();
|
||||
virtual opaque_coordinate<3> position();
|
||||
virtual opaque_coordinate<3> axis();
|
||||
virtual opaque_coordinate<4> plane_equation();
|
||||
|
||||
virtual std::vector<ConversionResultShape*> convex_decomposition();
|
||||
virtual ConversionResultShape* halfspaces();
|
||||
virtual ConversionResultShape* solid();
|
||||
virtual ConversionResultShape* box();
|
||||
virtual ConversionResultShape* wrap_in_compound();
|
||||
virtual std::vector<conversion_result_shape*> convex_decomposition();
|
||||
virtual conversion_result_shape* halfspaces();
|
||||
virtual conversion_result_shape* solid();
|
||||
virtual conversion_result_shape* box();
|
||||
virtual conversion_result_shape* wrap_in_compound();
|
||||
|
||||
virtual std::vector<ConversionResultShape*> vertices();
|
||||
virtual std::vector<ConversionResultShape*> edges();
|
||||
virtual std::vector<ConversionResultShape*> facets();
|
||||
virtual std::vector<conversion_result_shape*> vertices();
|
||||
virtual std::vector<conversion_result_shape*> edges();
|
||||
virtual std::vector<conversion_result_shape*> facets();
|
||||
|
||||
virtual ConversionResultShape* add(ConversionResultShape*);
|
||||
virtual ConversionResultShape* subtract(ConversionResultShape*);
|
||||
virtual ConversionResultShape* intersect(ConversionResultShape*);
|
||||
virtual ConversionResultShape* concat(ConversionResultShape*) {
|
||||
virtual conversion_result_shape* add(conversion_result_shape*);
|
||||
virtual conversion_result_shape* subtract(conversion_result_shape*);
|
||||
virtual conversion_result_shape* intersect(conversion_result_shape*);
|
||||
virtual conversion_result_shape* concat(conversion_result_shape*) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual std::size_t map(OpaqueCoordinate<4>& from, OpaqueCoordinate<4>& to);
|
||||
virtual std::size_t map(const std::vector<OpaqueCoordinate<4>>& from, const std::vector<OpaqueCoordinate<4>>& to);
|
||||
virtual ConversionResultShape* moved(ifcopenshell::geometry::taxonomy::matrix4::ptr) const;
|
||||
virtual std::size_t map(opaque_coordinate<4>& from, opaque_coordinate<4>& to);
|
||||
virtual std::size_t map(const std::vector<opaque_coordinate<4>>& from, const std::vector<opaque_coordinate<4>>& to);
|
||||
virtual conversion_result_shape* moved(ifcopenshell::geom::taxonomy::matrix4::ptr) const;
|
||||
|
||||
virtual bool surface_area_along_direction(double tol, const ifcopenshell::geometry::taxonomy::matrix4::ptr&, double& along_x, double& along_y, double& along_z) const {
|
||||
virtual bool surface_area_along_direction(double tol, const ifcopenshell::geom::taxonomy::matrix4::ptr&, double& along_x, double& along_y, double& along_z) const {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -372,7 +372,7 @@ namespace ifcopenshell { namespace geometry {
|
||||
}}
|
||||
|
||||
#ifdef IFOPSH_SIMPLE_KERNEL
|
||||
#undef CgalShape
|
||||
#undef cgal_shape
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -38,7 +38,7 @@ if ( it != cache.T.end() ) { e = it->second; return true; }
|
||||
*/
|
||||
|
||||
#ifdef IFOPSH_SIMPLE_KERNEL
|
||||
#define CgalKernel SimpleCgalKernel
|
||||
#define cgal_kernel SimpleCgalKernel
|
||||
#define create_cube create_cube_simple
|
||||
#define create_polyhedron create_polyhedron_simple
|
||||
#endif
|
||||
@@ -56,22 +56,22 @@ if ( it != cache.T.end() ) { e = it->second; return true; }
|
||||
#include <cmath>
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace geometry {
|
||||
namespace geom {
|
||||
namespace utils {
|
||||
IFC_GEOMLIBRARY_API CGAL::Polyhedron_3<Kernel_> create_cube(double d);
|
||||
IFC_GEOMLIBRARY_API CGAL::Polyhedron_3<Kernel_> create_cube(const Kernel_::Point_3& lower, const Kernel_::Point_3& upper);
|
||||
IFC_GEOMLIBRARY_API CGAL::Polyhedron_3<Kernel_> create_polyhedron(std::list<cgal_face_t> &face_list, bool stitch_borders = false, logger& logger = ::logger::root());
|
||||
IFC_GEOMLIBRARY_API CGAL::Polyhedron_3<kernel_> create_cube(double d);
|
||||
IFC_GEOMLIBRARY_API CGAL::Polyhedron_3<kernel_> create_cube(const kernel_::Point_3& lower, const kernel_::Point_3& upper);
|
||||
IFC_GEOMLIBRARY_API CGAL::Polyhedron_3<kernel_> create_polyhedron(std::list<cgal_face_t> &face_list, bool stitch_borders = false, logger& logger = ::logger::root());
|
||||
|
||||
#ifndef IFOPSH_SIMPLE_KERNEL
|
||||
IFC_GEOMLIBRARY_API CGAL::Polyhedron_3<Kernel_> create_polyhedron(const CGAL::Nef_polyhedron_3<Kernel_> &nef_polyhedron, logger& logger = ::logger::root());
|
||||
IFC_GEOMLIBRARY_API CGAL::Nef_polyhedron_3<Kernel_> create_nef_polyhedron(std::list<cgal_face_t> &face_list, logger& logger = ::logger::root());
|
||||
IFC_GEOMLIBRARY_API CGAL::Nef_polyhedron_3<Kernel_> create_nef_polyhedron(CGAL::Polyhedron_3<Kernel_> &polyhedron, logger& logger = ::logger::root());
|
||||
IFC_GEOMLIBRARY_API CGAL::Polyhedron_3<kernel_> create_polyhedron(const CGAL::Nef_polyhedron_3<kernel_> &nef_polyhedron, logger& logger = ::logger::root());
|
||||
IFC_GEOMLIBRARY_API CGAL::Nef_polyhedron_3<kernel_> create_nef_polyhedron(std::list<cgal_face_t> &face_list, logger& logger = ::logger::root());
|
||||
IFC_GEOMLIBRARY_API CGAL::Nef_polyhedron_3<kernel_> create_nef_polyhedron(CGAL::Polyhedron_3<kernel_> &polyhedron, logger& logger = ::logger::root());
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace kernels {
|
||||
|
||||
class IFC_GEOMLIBRARY_API CgalKernel : public AbstractKernel {
|
||||
class IFC_GEOMLIBRARY_API cgal_kernel : public abstract_kernel {
|
||||
private:
|
||||
#ifndef IFOPSH_SIMPLE_KERNEL
|
||||
enum boolean_operand_preprocess {
|
||||
@@ -82,23 +82,23 @@ namespace ifcopenshell {
|
||||
PP_NONE
|
||||
};
|
||||
|
||||
bool preprocess_boolean_operand(const express::Base& log_reference, const std::list<cgal_shape_t>& first_operands, const std::list<CGAL::Nef_polyhedron_3<Kernel_>>& first_operands_nef, const std::list<Kernel_::Plane_3>& all_operand_planes, const cgal_shape_t& shape_const, CGAL::Nef_polyhedron_3<Kernel_>& result, boolean_operand_preprocess proc);
|
||||
bool preprocess_boolean_operand(const express::base& log_reference, const std::list<cgal_shape_t>& first_operands, const std::list<CGAL::Nef_polyhedron_3<kernel_>>& first_operands_nef, const std::list<kernel_::Plane_3>& all_operand_planes, const cgal_shape_t& shape_const, CGAL::Nef_polyhedron_3<kernel_>& result, boolean_operand_preprocess proc);
|
||||
|
||||
bool thin_solid(const CGAL::Nef_polyhedron_3<Kernel_>& a, CGAL::Nef_polyhedron_3<Kernel_>& result);
|
||||
bool thin_solid(const CGAL::Nef_polyhedron_3<kernel_>& a, CGAL::Nef_polyhedron_3<kernel_>& result);
|
||||
|
||||
CGAL::Nef_polyhedron_3<Kernel_> create_precision_cube_() const {
|
||||
CGAL::Nef_polyhedron_3<kernel_> create_precision_cube_() const {
|
||||
auto cc = utils::create_cube(settings_.get<settings::Precision>().get());
|
||||
return CGAL::Nef_polyhedron_3<Kernel_>(cc);
|
||||
return CGAL::Nef_polyhedron_3<kernel_>(cc);
|
||||
}
|
||||
#endif
|
||||
public:
|
||||
|
||||
CgalKernel(const Settings& settings, ::logger& logger = ::logger::root())
|
||||
: AbstractKernel("cgal", settings, logger)
|
||||
cgal_kernel(const ifcopenshell::geom::settings& settings, ::logger& logger = ::logger::root())
|
||||
: abstract_kernel("cgal", settings, logger)
|
||||
{}
|
||||
|
||||
virtual AbstractKernel* clone(::logger& logger) const {
|
||||
return new CgalKernel(settings(), logger);
|
||||
virtual abstract_kernel* clone(::logger& logger) const {
|
||||
return new cgal_kernel(settings(), logger);
|
||||
}
|
||||
|
||||
virtual bool supports_boolean_operations() const {
|
||||
@@ -116,19 +116,19 @@ namespace ifcopenshell {
|
||||
bool convert(const taxonomy::shell::ptr, cgal_shape_t&);
|
||||
|
||||
bool process_extrusion(const cgal_face_t& bottom_face, taxonomy::direction3::ptr direction, double height, cgal_shape_t& shape);
|
||||
bool process_as_2d_polygon(const taxonomy::boolean_result::ptr br, std::list<CGAL::Polygon_2<Kernel_>>& loops, double& z0, double& z1);
|
||||
bool process_as_2d_polygon(const std::list<std::list<std::pair<express::Base, cgal_shape_t>>>& operands, std::list<CGAL::Polygon_2<Kernel_>>& loops, double& z0, double& z1);
|
||||
bool process_as_2d_polygon(const taxonomy::boolean_result::ptr br, std::list<CGAL::Polygon_2<kernel_>>& loops, double& z0, double& z1);
|
||||
bool process_as_2d_polygon(const std::list<std::list<std::pair<express::base, cgal_shape_t>>>& operands, std::list<CGAL::Polygon_2<kernel_>>& loops, double& z0, double& z1);
|
||||
|
||||
virtual bool convert_impl(const taxonomy::shell::ptr, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const taxonomy::extrusion::ptr, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const taxonomy::boolean_result::ptr, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const taxonomy::solid::ptr, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const taxonomy::shell::ptr, ifcopenshell::geom::conversion_results&);
|
||||
virtual bool convert_impl(const taxonomy::extrusion::ptr, ifcopenshell::geom::conversion_results&);
|
||||
virtual bool convert_impl(const taxonomy::boolean_result::ptr, ifcopenshell::geom::conversion_results&);
|
||||
virtual bool convert_impl(const taxonomy::solid::ptr, ifcopenshell::geom::conversion_results&);
|
||||
|
||||
virtual bool convert_openings(const express::Base& entity, const std::vector<std::pair<taxonomy::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
|
||||
const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes);
|
||||
virtual bool convert_openings(const express::base& entity, const std::vector<std::pair<taxonomy::ptr, ifcopenshell::geom::taxonomy::matrix4>>& openings,
|
||||
const ifcopenshell::geom::conversion_results& entity_shapes, const ifcopenshell::geom::taxonomy::matrix4& entity_trsf, ifcopenshell::geom::conversion_results& cut_shapes);
|
||||
|
||||
#ifndef IFOPSH_SIMPLE_KERNEL
|
||||
CGAL::Nef_polyhedron_3<Kernel_> precision_cube() const { return create_precision_cube_(); }
|
||||
CGAL::Nef_polyhedron_3<kernel_> precision_cube() const { return create_precision_cube_(); }
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
// Functor to lexicographically sort Plane_3
|
||||
template <typename Kernel>
|
||||
struct PlaneLess {
|
||||
struct plane_less {
|
||||
bool operator()(const typename Kernel::Plane_3& lhs, const typename Kernel::Plane_3& rhs) const {
|
||||
auto lhs_a = lhs.a();
|
||||
auto lhs_b = lhs.b();
|
||||
@@ -70,7 +70,7 @@ struct PlaneLess {
|
||||
|
||||
// Functor to hash Plane_3
|
||||
template <typename Kernel>
|
||||
struct PlaneHash {
|
||||
struct plane_hash {
|
||||
size_t operator()(const CGAL::Plane_3<Kernel>& plane) const noexcept
|
||||
{
|
||||
// @todo why can I only get this to work on double?
|
||||
@@ -86,8 +86,8 @@ struct PlaneHash {
|
||||
// Utility function to return Nef facet information as string
|
||||
template <typename Kernel>
|
||||
std::string dump_facet(typename CGAL::Nef_polyhedron_3<Kernel>::Halffacet_const_handle h) {
|
||||
typedef typename CGAL::Nef_polyhedron_3<Kernel>::SHalfedge_const_handle SHalfedge_const_handle;
|
||||
typedef typename CGAL::Nef_polyhedron_3<Kernel>::SHalfedge_around_facet_const_circulator SHalfedge_around_facet_const_circulator;
|
||||
typedef typename CGAL::Nef_polyhedron_3<Kernel>::SHalfedge_const_handle shalfedge_const_handle;
|
||||
typedef typename CGAL::Nef_polyhedron_3<Kernel>::SHalfedge_around_facet_const_circulator shalfedge_around_facet_const_circulator;
|
||||
|
||||
std::ostringstream oss;
|
||||
|
||||
@@ -95,10 +95,10 @@ std::string dump_facet(typename CGAL::Nef_polyhedron_3<Kernel>::Halffacet_const_
|
||||
oss << "Facet plane=" << p << std::endl;
|
||||
|
||||
auto fc = h->facet_cycles_begin();
|
||||
auto se = SHalfedge_const_handle(fc);
|
||||
auto se = shalfedge_const_handle(fc);
|
||||
CGAL_assertion(se != 0);
|
||||
SHalfedge_around_facet_const_circulator hc_start(se);
|
||||
SHalfedge_around_facet_const_circulator hc_end(hc_start);
|
||||
shalfedge_around_facet_const_circulator hc_start(se);
|
||||
shalfedge_around_facet_const_circulator hc_end(hc_start);
|
||||
CGAL_For_all(hc_start, hc_end) {
|
||||
oss << " co=" << hc_start->source()->center_vertex()->point() << std::endl;
|
||||
}
|
||||
@@ -114,8 +114,8 @@ enum halfspace_operation {
|
||||
|
||||
// Map of Plane_3 -> Plane_3 used when applied snapping
|
||||
template <typename Kernel>
|
||||
using plane_map = std::map<typename Kernel::Plane_3, typename Kernel::Plane_3, PlaneLess<Kernel>>;
|
||||
// using plane_map = std::unordered_map<typename Kernel::Plane_3, typename Kernel::Plane_3, PlaneHash<Kernel>>;
|
||||
using plane_map = std::map<typename Kernel::Plane_3, typename Kernel::Plane_3, plane_less<Kernel>>;
|
||||
// using plane_map = std::unordered_map<typename Kernel::Plane_3, typename Kernel::Plane_3, plane_hash<Kernel>>;
|
||||
|
||||
template <typename Kernel>
|
||||
typename Kernel::Plane_3 normalized_plane_for_map(const typename Kernel::Plane_3& plane) {
|
||||
@@ -134,10 +134,10 @@ typename Kernel::Plane_3 normalized_plane_for_map(const typename Kernel::Plane_3
|
||||
);
|
||||
}
|
||||
|
||||
// Lexicographic comparator for CGAL Point_d (operator< is deleted in CGAL 6.x)
|
||||
struct Point_d_4d_Less {
|
||||
using Point_d = CGAL::Epick_d<CGAL::Dimension_tag<4>>::Point_d;
|
||||
bool operator()(const Point_d& a, const Point_d& b) const {
|
||||
// Lexicographic comparator for CGAL point_d (operator< is deleted in CGAL 6.x)
|
||||
struct point_d_4d_less {
|
||||
using point_d = CGAL::Epick_d<CGAL::Dimension_tag<4>>::Point_d;
|
||||
bool operator()(const point_d& a, const point_d& b) const {
|
||||
return std::lexicographical_compare(
|
||||
a.cartesian_begin(), a.cartesian_end(),
|
||||
b.cartesian_begin(), b.cartesian_end());
|
||||
@@ -151,29 +151,29 @@ plane_map<Kernel> snap_halfspaces(const std::list<CGAL::Plane_3<Kernel>>& planes
|
||||
// @todo this should incorporate some recursive or actual clustering approach so that
|
||||
// in cases of many approximate neighbours it still produces good results.
|
||||
|
||||
typedef CGAL::Epick_d<CGAL::Dimension_tag<4>> KdKernel;
|
||||
typedef KdKernel::Point_d Point_d;
|
||||
typedef CGAL::Search_traits_d<KdKernel> TreeTraits;
|
||||
typedef CGAL::Kd_tree<TreeTraits> Tree;
|
||||
typedef CGAL::Fuzzy_sphere<TreeTraits> Fuzzy_sphere;
|
||||
typedef CGAL::Epick_d<CGAL::Dimension_tag<4>> kd_kernel;
|
||||
typedef kd_kernel::Point_d point_d;
|
||||
typedef CGAL::Search_traits_d<kd_kernel> tree_traits;
|
||||
typedef CGAL::Kd_tree<tree_traits> tree;
|
||||
typedef CGAL::Fuzzy_sphere<tree_traits> fuzzy_sphere;
|
||||
|
||||
plane_map<Kernel> result;
|
||||
|
||||
std::map<Point_d, std::set<Point_d, Point_d_4d_Less>, Point_d_4d_Less> neighbours;
|
||||
std::map<Point_d, std::list<CGAL::Plane_3<Kernel>>, Point_d_4d_Less> originals;
|
||||
std::vector<Point_d> planes_as_point;
|
||||
std::map<point_d, std::set<point_d, point_d_4d_less>, point_d_4d_less> neighbours;
|
||||
std::map<point_d, std::list<CGAL::Plane_3<Kernel>>, point_d_4d_less> originals;
|
||||
std::vector<point_d> planes_as_point;
|
||||
|
||||
for (auto& p : planes) {
|
||||
// @todo can we skip normalization (simply divide by largest component perhaps)
|
||||
double l = std::sqrt(CGAL::to_double(p.orthogonal_vector().squared_length()));
|
||||
// @todo how to properly initialize using p._().exact() without converting to double?
|
||||
Point_d pp(CGAL::to_double(p.a()) / l, CGAL::to_double(p.b()) / l, CGAL::to_double(p.c()) / l, CGAL::to_double(p.d()) / l);
|
||||
point_d pp(CGAL::to_double(p.a()) / l, CGAL::to_double(p.b()) / l, CGAL::to_double(p.c()) / l, CGAL::to_double(p.d()) / l);
|
||||
planes_as_point.push_back(pp);
|
||||
originals[pp].push_back(p);
|
||||
}
|
||||
|
||||
// @todo should we have a proper distance metric for plane equations
|
||||
Tree kdtree(planes_as_point.begin(), planes_as_point.end());
|
||||
tree kdtree(planes_as_point.begin(), planes_as_point.end());
|
||||
|
||||
auto plit = planes.begin();
|
||||
for (size_t i = 0; i < planes.size(); ++i) {
|
||||
@@ -183,19 +183,19 @@ plane_map<Kernel> snap_halfspaces(const std::list<CGAL::Plane_3<Kernel>>& planes
|
||||
|
||||
auto& query = planes_as_point[i];
|
||||
|
||||
Fuzzy_sphere fs(query, search_radius, 0.);
|
||||
fuzzy_sphere fs(query, search_radius, 0.);
|
||||
// std::cout << "q " << query << std::endl;
|
||||
|
||||
std::list<Point_d> results_pos, results_neg;
|
||||
std::list<point_d> results_pos, results_neg;
|
||||
kdtree.search(std::back_inserter(results_pos), fs);
|
||||
|
||||
Point_d n(-query[0], -query[1], -query[2], -query[3]);
|
||||
Fuzzy_sphere fsn(n, search_radius, 0.);
|
||||
point_d n(-query[0], -query[1], -query[2], -query[3]);
|
||||
fuzzy_sphere fsn(n, search_radius, 0.);
|
||||
kdtree.search(std::back_inserter(results_neg), fsn);
|
||||
|
||||
auto sum = std::accumulate(++results_pos.begin(), results_pos.end(), results_pos.front(), [](Point_d a, Point_d b) {return Point_d(a[0] + b[0], a[1] + b[1], a[2] + b[2], a[3] + b[3]); });
|
||||
auto sum = std::accumulate(++results_pos.begin(), results_pos.end(), results_pos.front(), [](point_d a, point_d b) {return point_d(a[0] + b[0], a[1] + b[1], a[2] + b[2], a[3] + b[3]); });
|
||||
int N = results_pos.size();
|
||||
auto sum2 = std::accumulate(results_neg.begin(), results_neg.end(), sum, [](Point_d a, Point_d b) {return Point_d(a[0] - b[0], a[1] - b[1], a[2] - b[2], a[3] - b[3]); });
|
||||
auto sum2 = std::accumulate(results_neg.begin(), results_neg.end(), sum, [](point_d a, point_d b) {return point_d(a[0] - b[0], a[1] - b[1], a[2] - b[2], a[3] - b[3]); });
|
||||
N += results_neg.size();
|
||||
|
||||
auto avg = CGAL::Plane_3<Kernel>(sum2[0] / N, sum2[1] / N, sum2[2] / N, sum2[3] / N);
|
||||
@@ -224,45 +224,45 @@ plane_map<Kernel> snap_halfspaces_2(const std::list<CGAL::Plane_3<Kernel>>& plan
|
||||
// @todo this should incorporate some recursive or actual clustering approach so that
|
||||
// in cases of many approximate neighbours it still produces good results.
|
||||
|
||||
typedef CGAL::Epick_d<CGAL::Dimension_tag<4>> KdKernel;
|
||||
typedef KdKernel::Point_d Point_d;
|
||||
typedef CGAL::Search_traits_d<KdKernel> TreeTraits;
|
||||
typedef CGAL::Kd_tree<TreeTraits> Tree;
|
||||
typedef CGAL::Fuzzy_sphere<TreeTraits> Fuzzy_sphere;
|
||||
typedef CGAL::Epick_d<CGAL::Dimension_tag<4>> kd_kernel;
|
||||
typedef kd_kernel::Point_d point_d;
|
||||
typedef CGAL::Search_traits_d<kd_kernel> tree_traits;
|
||||
typedef CGAL::Kd_tree<tree_traits> tree;
|
||||
typedef CGAL::Fuzzy_sphere<tree_traits> fuzzy_sphere;
|
||||
|
||||
plane_map<Kernel> result;
|
||||
|
||||
std::vector<Point_d> planes_as_point;
|
||||
std::map<Point_d, CGAL::Plane_3<Kernel>, Point_d_4d_Less> normalized_to_original;
|
||||
std::vector<point_d> planes_as_point;
|
||||
std::map<point_d, CGAL::Plane_3<Kernel>, point_d_4d_less> normalized_to_original;
|
||||
|
||||
for (auto& p : planes_fixed) {
|
||||
// @todo can we skip normalization (simply divide by largest component perhaps)
|
||||
double l = std::sqrt(CGAL::to_double(p.orthogonal_vector().squared_length()));
|
||||
// @todo how to properly initialize using p._().exact() without converting to double?
|
||||
Point_d pp(CGAL::to_double(p.a()) / l, CGAL::to_double(p.b()) / l, CGAL::to_double(p.c()) / l, CGAL::to_double(p.d()) / l);
|
||||
point_d pp(CGAL::to_double(p.a()) / l, CGAL::to_double(p.b()) / l, CGAL::to_double(p.c()) / l, CGAL::to_double(p.d()) / l);
|
||||
planes_as_point.push_back(pp);
|
||||
normalized_to_original.insert({ pp, p });
|
||||
}
|
||||
|
||||
// @todo should we have a proper distance metric for plane equations
|
||||
Tree kdtree(planes_as_point.begin(), planes_as_point.end());
|
||||
tree kdtree(planes_as_point.begin(), planes_as_point.end());
|
||||
|
||||
auto plit = planes.begin();
|
||||
for (; plit != planes.end(); ++plit) {
|
||||
// @todo rewrite to use 1 nearest neighbour
|
||||
double l = std::sqrt(CGAL::to_double(plit->orthogonal_vector().squared_length()));
|
||||
Point_d query(CGAL::to_double(plit->a()) / l, CGAL::to_double(plit->b()) / l, CGAL::to_double(plit->c()) / l, CGAL::to_double(plit->d()) / l);
|
||||
Fuzzy_sphere fs(query, search_radius, 0.);
|
||||
point_d query(CGAL::to_double(plit->a()) / l, CGAL::to_double(plit->b()) / l, CGAL::to_double(plit->c()) / l, CGAL::to_double(plit->d()) / l);
|
||||
fuzzy_sphere fs(query, search_radius, 0.);
|
||||
// std::cout << "q " << *plit << std::endl;
|
||||
|
||||
std::list<Point_d> results;
|
||||
std::list<point_d> results;
|
||||
kdtree.search(std::back_inserter(results), fs);
|
||||
if (!results.empty()) {
|
||||
result.insert({ *plit, normalized_to_original.find(results.front())->second });
|
||||
// std::cout << " " << normalized_to_original.find(results.front())->second << std::endl;
|
||||
} else {
|
||||
Point_d n(-query[0], -query[1], -query[2], -query[3]);
|
||||
Fuzzy_sphere fsn(n, search_radius, 0.);
|
||||
point_d n(-query[0], -query[1], -query[2], -query[3]);
|
||||
fuzzy_sphere fsn(n, search_radius, 0.);
|
||||
kdtree.search(std::back_inserter(results), fsn);
|
||||
if (!results.empty()) {
|
||||
result.insert({ *plit, normalized_to_original.find(results.front())->second.opposite() });
|
||||
@@ -450,14 +450,14 @@ void extrude(LoopType bottom, const CGAL::Vector_3<Kernel>& V, CGAL::Polyhedron_
|
||||
// Create cube of half-distance d
|
||||
template <typename Kernel>
|
||||
void createCube(CGAL::Polyhedron_3<Kernel>& P, double d) {
|
||||
typedef CGAL::Point_3<Kernel> Point;
|
||||
typedef std::array<CGAL::Point_3<Kernel>, 4> Quad;
|
||||
typedef CGAL::Point_3<Kernel> point;
|
||||
typedef std::array<CGAL::Point_3<Kernel>, 4> quad;
|
||||
|
||||
Quad bottom = { {
|
||||
Point(-d, -d, -d),
|
||||
Point(+d, -d, -d),
|
||||
Point(+d, +d, -d),
|
||||
Point(-d, +d, -d)
|
||||
quad bottom = { {
|
||||
point(-d, -d, -d),
|
||||
point(+d, -d, -d),
|
||||
point(+d, +d, -d),
|
||||
point(-d, +d, -d)
|
||||
} };
|
||||
|
||||
CGAL::Vector_3<Kernel> V(0, 0, d * 2);
|
||||
@@ -523,11 +523,11 @@ public:
|
||||
// Triangulate a nef facet. Used for intersection check to find convex subcomponent
|
||||
template <typename Kernel>
|
||||
std::vector<CGAL::Triangle_3<Kernel>> triangulate_nef_facet(typename CGAL::Nef_polyhedron_3<Kernel>::Halffacet_const_handle f) {
|
||||
typedef typename CGAL::Nef_polyhedron_3<Kernel>::SHalfedge_around_facet_const_circulator SHalfedge_around_facet_const_circulator;
|
||||
typedef typename CGAL::Nef_polyhedron_3<Kernel>::SHalfedge_around_facet_const_circulator shalfedge_around_facet_const_circulator;
|
||||
|
||||
std::vector<typename Kernel::Point_3> ps;
|
||||
SHalfedge_around_facet_const_circulator it(f->facet_cycles_begin());
|
||||
SHalfedge_around_facet_const_circulator first(it);
|
||||
shalfedge_around_facet_const_circulator it(f->facet_cycles_begin());
|
||||
shalfedge_around_facet_const_circulator first(it);
|
||||
CGAL_For_all(it, first) {
|
||||
ps.push_back(it->source()->center_vertex()->point());
|
||||
}
|
||||
@@ -548,25 +548,25 @@ std::vector<CGAL::Triangle_3<Kernel>> triangulate_nef_facet(typename CGAL::Nef_p
|
||||
enum EdgeType { CONCAVE, CONVEX };
|
||||
|
||||
template <typename Kernel>
|
||||
struct VertexProperties {
|
||||
struct vertex_properties {
|
||||
typename CGAL::Nef_polyhedron_3<Kernel>::Halffacet_const_handle facet;
|
||||
size_t original_index;
|
||||
};
|
||||
|
||||
template <typename Kernel>
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS,
|
||||
VertexProperties<Kernel>,
|
||||
using graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS,
|
||||
vertex_properties<Kernel>,
|
||||
boost::property<boost::edge_weight_t, EdgeType>>;
|
||||
|
||||
// Build a boost graph with vertex corresponding to Nef facet, edge corresponding to Nef edge
|
||||
// marked as reflex or not.
|
||||
template <typename Kernel>
|
||||
Graph<Kernel> build_facet_edge_graph(const CGAL::Nef_polyhedron_3<Kernel>& poly) {
|
||||
typedef typename CGAL::Nef_polyhedron_3<Kernel>::Halffacet_const_handle Halffacet_const_handle;
|
||||
graph<Kernel> build_facet_edge_graph(const CGAL::Nef_polyhedron_3<Kernel>& poly) {
|
||||
typedef typename CGAL::Nef_polyhedron_3<Kernel>::Halffacet_const_handle halffacet_const_handle;
|
||||
|
||||
Graph<Kernel> G;
|
||||
graph<Kernel> G;
|
||||
|
||||
std::map<Halffacet_const_handle, size_t> facet_to_idx;
|
||||
std::map<halffacet_const_handle, size_t> facet_to_idx;
|
||||
|
||||
for (auto it = poly.vertices_begin(); it != poly.vertices_end(); ++it) {
|
||||
for (auto a = it->shalfedges_begin(); a != it->shalfedges_end(); ++a) {
|
||||
@@ -617,14 +617,14 @@ Graph<Kernel> build_facet_edge_graph(const CGAL::Nef_polyhedron_3<Kernel>& poly)
|
||||
}
|
||||
|
||||
template <typename Kernel>
|
||||
void dump_facets(Graph<Kernel>& G) {
|
||||
void dump_facets(graph<Kernel>& G) {
|
||||
for (size_t ii = 0; ii < boost::num_vertices(G); ++ii) {
|
||||
// std::cout << ii << " " << dump_facet<Kernel>(G[ii].facet) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
struct Intersection_visitor {
|
||||
struct intersection_visitor {
|
||||
typedef void result_type;
|
||||
void operator()(const Kernel::Point_3& p) const
|
||||
{
|
||||
@@ -642,7 +642,7 @@ struct Intersection_visitor {
|
||||
*/
|
||||
|
||||
template <typename Kernel>
|
||||
struct Segment_collector {
|
||||
struct segment_collector {
|
||||
typedef void result_type;
|
||||
std::optional<CGAL::Segment_3<Kernel>> segment;
|
||||
|
||||
@@ -669,8 +669,8 @@ public:
|
||||
convex_subcomponent_visitor(EdgeType edgetype, ComponentMap& component)
|
||||
: edgetype_(edgetype), components_(component) {}
|
||||
|
||||
template <typename Edge, typename Graph>
|
||||
bool tree_edge(Edge e, const Graph& g) {
|
||||
template <typename Edge, typename graph>
|
||||
bool tree_edge(Edge e, const graph& g) {
|
||||
if (std::get(boost::edge_weight, g, e) == edgetype_) {
|
||||
auto srcid = boost::source(e, g);
|
||||
auto tgtid = boost::target(e, g);
|
||||
@@ -688,7 +688,7 @@ public:
|
||||
if (*tgt == -1) {
|
||||
bool tgt_has_any_reflex_edge = false;
|
||||
|
||||
typename boost::graph_traits<Graph>::out_edge_iterator ei, ei_end;
|
||||
typename boost::graph_traits<graph>::out_edge_iterator ei, ei_end;
|
||||
for (boost::tie(ei, ei_end) = boost::out_edges(tgtid, g); ei != ei_end; ++ei) {
|
||||
if (std::get(boost::edge_weight, g, *ei) != edgetype_) {
|
||||
tgt_has_any_reflex_edge = true;
|
||||
@@ -734,9 +734,9 @@ public:
|
||||
auto x = CGAL::intersection(plane_tgt, t);
|
||||
if (x) {
|
||||
// std::cout << " triangle: " << t << std::endl;
|
||||
// Intersection_visitor v;
|
||||
// intersection_visitor v;
|
||||
// std::visit([](auto x) {std::cout << " intersects: " << x << std::endl; })(*x);
|
||||
Segment_collector<Kernel> sc;
|
||||
segment_collector<Kernel> sc;
|
||||
std::visit(sc)(*x);
|
||||
if (sc.segment) {
|
||||
if (!std::any_of(edges_i.begin(), edges_i.end(), [&sc](CGAL::Segment_3<Kernel>& s) {
|
||||
@@ -745,7 +745,7 @@ public:
|
||||
if (!xy) {
|
||||
return false;
|
||||
}
|
||||
Segment_collector<Kernel> scy;
|
||||
segment_collector<Kernel> scy;
|
||||
std::visit(scy)(*xy);
|
||||
return (bool)scy.segment;
|
||||
})) {
|
||||
@@ -784,7 +784,7 @@ public:
|
||||
|
||||
// bfs implementation to that respects a predicate on determining whether an edge is applicable
|
||||
template <typename Kernel, typename Fn>
|
||||
void bfs(Graph<Kernel>& g, size_t start_vertex, Fn& fn) {
|
||||
void bfs(graph<Kernel>& g, size_t start_vertex, Fn& fn) {
|
||||
std::queue<size_t> queue;
|
||||
queue.push(start_vertex);
|
||||
|
||||
@@ -795,7 +795,7 @@ void bfs(Graph<Kernel>& g, size_t start_vertex, Fn& fn) {
|
||||
auto cur = queue.front();
|
||||
queue.pop();
|
||||
|
||||
typename boost::graph_traits<Graph<Kernel>>::out_edge_iterator ei, ei_end;
|
||||
typename boost::graph_traits<graph<Kernel>>::out_edge_iterator ei, ei_end;
|
||||
for (boost::tie(ei, ei_end) = boost::out_edges(cur, g); ei != ei_end; ++ei) {
|
||||
auto s = boost::source(*ei, g);
|
||||
auto t = boost::target(*ei, g);
|
||||
@@ -821,14 +821,14 @@ void bfs(Graph<Kernel>& g, size_t start_vertex, Fn& fn) {
|
||||
// builds a tree of halfspaces from an input nef polyhedron
|
||||
// checks whether output is equivalent and if not uses a convex decomposition first
|
||||
template <typename Kernel, typename TreeKernel=Kernel>
|
||||
std::unique_ptr<halfspace_tree<TreeKernel>> build_halfspace_tree(Graph<Kernel>& G, CGAL::Nef_polyhedron_3<Kernel>& poly, bool negate = false, int level=0) {
|
||||
typedef boost::filtered_graph<Graph<Kernel>, boost::keep_all, std::function<bool(typename Graph<Kernel>::vertex_descriptor)>> FilteredGraph;
|
||||
std::unique_ptr<halfspace_tree<TreeKernel>> build_halfspace_tree(graph<Kernel>& G, CGAL::Nef_polyhedron_3<Kernel>& poly, bool negate = false, int level=0) {
|
||||
typedef boost::filtered_graph<graph<Kernel>, boost::keep_all, std::function<bool(typename graph<Kernel>::vertex_descriptor)>> filtered_graph;
|
||||
|
||||
auto edge_trait = negate ? CONCAVE : CONVEX;
|
||||
|
||||
/*
|
||||
bool all_convex = true;
|
||||
typename boost::graph_traits<Graph<Kernel>>::edge_iterator ei, ei_end;
|
||||
typename boost::graph_traits<graph<Kernel>>::edge_iterator ei, ei_end;
|
||||
for (boost::tie(ei, ei_end) = boost::edges(G); ei != ei_end; ++ei) {
|
||||
if (std::get(boost::edge_weight, G, *ei) != edge_trait) {
|
||||
// all_convex = false;
|
||||
@@ -850,11 +850,11 @@ std::unique_ptr<halfspace_tree<TreeKernel>> build_halfspace_tree(Graph<Kernel>&
|
||||
std::unique_ptr<halfspace_tree<TreeKernel>> tree;
|
||||
std::list<std::unique_ptr<halfspace_tree<TreeKernel>>> root_expression;
|
||||
|
||||
auto included_in_vertex_subset_0 = [&components_0, &i](typename Graph<Kernel>::vertex_descriptor vd) {
|
||||
auto included_in_vertex_subset_0 = [&components_0, &i](typename graph<Kernel>::vertex_descriptor vd) {
|
||||
return components_0[vd] == i;
|
||||
};
|
||||
FilteredGraph sub_graph_filtered_0(G, boost::keep_all{}, included_in_vertex_subset_0);
|
||||
Graph<Kernel> sub_graph_0;
|
||||
filtered_graph sub_graph_filtered_0(G, boost::keep_all{}, included_in_vertex_subset_0);
|
||||
graph<Kernel> sub_graph_0;
|
||||
boost::copy_graph(sub_graph_filtered_0, sub_graph_0);
|
||||
|
||||
std::vector<int> components(boost::num_vertices(sub_graph_0), -1);
|
||||
@@ -915,7 +915,7 @@ std::unique_ptr<halfspace_tree<TreeKernel>> build_halfspace_tree(Graph<Kernel>&
|
||||
|
||||
size_t vidx = 0;
|
||||
// Convex decomposition is not always optimal, sometimes contains coplanar facets
|
||||
std::unordered_set<typename Kernel::Plane_3, PlaneHash<Kernel>> plane_set;
|
||||
std::unordered_set<typename Kernel::Plane_3, plane_hash<Kernel>> plane_set;
|
||||
for (auto it = components.begin(); it != components.end(); ++it, ++vidx) {
|
||||
auto fct = sub_graph_0[vidx].facet;
|
||||
if (negate) {
|
||||
@@ -929,11 +929,11 @@ std::unique_ptr<halfspace_tree<TreeKernel>> build_halfspace_tree(Graph<Kernel>&
|
||||
|
||||
tree.reset(new halfspace_tree_nary_branch<TreeKernel>(OP_INTERSECTION, std::move(root_expression)));
|
||||
|
||||
auto included_in_vertex_subset = [&components, &largest_component_idx](typename Graph<Kernel>::vertex_descriptor vd) {
|
||||
auto included_in_vertex_subset = [&components, &largest_component_idx](typename graph<Kernel>::vertex_descriptor vd) {
|
||||
return components[vd] != largest_component_idx;
|
||||
};
|
||||
FilteredGraph sub_graph_filtered(sub_graph_0, boost::keep_all{}, included_in_vertex_subset);
|
||||
Graph<Kernel> sub_graph;
|
||||
filtered_graph sub_graph_filtered(sub_graph_0, boost::keep_all{}, included_in_vertex_subset);
|
||||
graph<Kernel> sub_graph;
|
||||
// @todo can we go without this copy?
|
||||
boost::copy_graph(sub_graph_filtered, sub_graph);
|
||||
|
||||
@@ -1011,7 +1011,7 @@ std::unique_ptr<halfspace_tree<TreeKernel>> build_halfspace_tree(Graph<Kernel>&
|
||||
// using the Polygon_mesh_processing package and Polygon_triangulation_decomposition_2
|
||||
// in case of facets with inner bounds.
|
||||
template <typename Kernel>
|
||||
struct Halffacet_collector {
|
||||
struct halffacet_collector {
|
||||
std::set<typename CGAL::Nef_polyhedron_3<Kernel>::Halffacet_const_handle> facets;
|
||||
void visit(typename CGAL::Nef_polyhedron_3<Kernel>::Vertex_const_handle) {}
|
||||
void visit(typename CGAL::Nef_polyhedron_3<Kernel>::Halfedge_const_handle) {}
|
||||
@@ -1029,7 +1029,7 @@ struct Halffacet_collector {
|
||||
// using the Polygon_mesh_processing package and Polygon_triangulation_decomposition_2
|
||||
// in case of facets with inner bounds.
|
||||
template <typename Kernel, bool eliminate_tiny_facets=false>
|
||||
class Polysoup_builder {
|
||||
class polysoup_builder {
|
||||
private:
|
||||
std::map<CGAL::Point_3<Kernel>, size_t> verts;
|
||||
std::vector<std::vector<size_t>> facets;
|
||||
@@ -1219,7 +1219,7 @@ std::unique_ptr<halfspace_tree<TreeKernel>> build_halfspace_tree_decomposed(cons
|
||||
std::list<std::unique_ptr<halfspace_tree<TreeKernel>>> sub_expression;
|
||||
|
||||
if (ci->mark()) {
|
||||
Halffacet_collector<Kernel> vis;
|
||||
halffacet_collector<Kernel> vis;
|
||||
poly.visit_shell_objects(typename CGAL::Nef_polyhedron_3<Kernel>::SFace_const_handle(ci->shells_begin()), vis);
|
||||
for (auto& f : vis.facets) {
|
||||
sub_expression.emplace_back(new halfspace_tree_plane<TreeKernel>(f->plane()));
|
||||
@@ -1240,7 +1240,7 @@ std::unique_ptr<halfspace_tree<TreeKernel>> build_halfspace_tree_decomposed(cons
|
||||
|
||||
if (sub_expression.size() != vis.facets.size()) {
|
||||
|
||||
Polysoup_builder<Kernel> vis2;
|
||||
polysoup_builder<Kernel> vis2;
|
||||
poly.visit_shell_objects(CGAL::Nef_polyhedron_3<Kernel>::SFace_const_handle(ci->shells_begin()), vis2);
|
||||
|
||||
{
|
||||
@@ -1294,9 +1294,9 @@ std::unique_ptr<halfspace_tree<TreeKernel>> build_halfspace_tree_is_decomposed(c
|
||||
}
|
||||
|
||||
template <typename Kernel>
|
||||
size_t edge_contract(Graph<Kernel>& G) {
|
||||
size_t edge_contract(graph<Kernel>& G) {
|
||||
size_t n = 0;
|
||||
typename boost::graph_traits<Graph<Kernel>>::edge_iterator ei, ei_end;
|
||||
typename boost::graph_traits<graph<Kernel>>::edge_iterator ei, ei_end;
|
||||
bool has_contracted = true;
|
||||
while (has_contracted) {
|
||||
has_contracted = false;
|
||||
@@ -1334,7 +1334,7 @@ template <typename Kernel>
|
||||
bool convert_to_polyhedron(const CGAL::Nef_polyhedron_3<Kernel>& a, CGAL::Polyhedron_3<Kernel>& b, size_t volume_index=0) {
|
||||
const bool all_volumes = volume_index == std::numeric_limits<size_t>::max();
|
||||
size_t v = 0;
|
||||
Polysoup_builder<Kernel> vis;
|
||||
polysoup_builder<Kernel> vis;
|
||||
for (auto it = a.volumes_begin(); it != a.volumes_end(); ++it) {
|
||||
if (!it->mark()) {
|
||||
continue;
|
||||
@@ -1359,7 +1359,7 @@ bool convert_to_polyhedron(const CGAL::Nef_polyhedron_3<Kernel>& a, CGAL::Polyhe
|
||||
template <typename Kernel>
|
||||
bool write_to_obj(const CGAL::Nef_polyhedron_3<Kernel>& a, std::ostream& ofs, size_t volume_index = 0) {
|
||||
size_t v = 0;
|
||||
Polysoup_builder<Kernel> vis;
|
||||
polysoup_builder<Kernel> vis;
|
||||
for (auto it = a.volumes_begin(); it != a.volumes_end(); ++it) {
|
||||
if (!it->mark()) {
|
||||
continue;
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#endif
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace geometry {
|
||||
namespace geom {
|
||||
namespace kernels {
|
||||
namespace cgal_plugin {
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace ifcopenshell {
|
||||
constexpr const char* plugin_name = "cgal";
|
||||
constexpr const char* backend_id = "cgal";
|
||||
constexpr bool supports_boolean_operations = true;
|
||||
using kernel_type = CgalKernel;
|
||||
using kernel_type = cgal_kernel;
|
||||
#endif
|
||||
|
||||
plugin::abi_info plugin_abi() {
|
||||
@@ -51,7 +51,7 @@ namespace ifcopenshell {
|
||||
return kernel_plugin_metadata(plugin_name);
|
||||
}
|
||||
|
||||
AbstractKernel* create_kernel(ifcopenshell::file*, Settings& settings) {
|
||||
abstract_kernel* create_kernel(ifcopenshell::file*, ifcopenshell::geom::settings& settings) {
|
||||
return new kernel_type(settings);
|
||||
}
|
||||
|
||||
@@ -67,6 +67,6 @@ namespace ifcopenshell {
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geometry::kernels::cgal_plugin::plugin_abi, ifcopenshell_plugin_abi_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geometry::kernels::cgal_plugin::plugin_metadata, ifcopenshell_plugin_metadata_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geometry::kernels::cgal_plugin::register_plugin, ifcopenshell_register_kernel_plugin_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geom::kernels::cgal_plugin::plugin_abi, ifcopenshell_plugin_abi_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geom::kernels::cgal_plugin::plugin_metadata, ifcopenshell_plugin_metadata_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geom::kernels::cgal_plugin::register_plugin, ifcopenshell_register_kernel_plugin_v1)
|
||||
|
||||
@@ -10,15 +10,15 @@
|
||||
#include <sstream>
|
||||
#include <unordered_map>
|
||||
|
||||
using IfcGeom::ConversionResultShape;
|
||||
using IfcGeom::OpaqueCoordinate;
|
||||
using IfcGeom::OpaqueNumber;
|
||||
using ifcopenshell::geom::conversion_result_shape;
|
||||
using ifcopenshell::geom::opaque_coordinate;
|
||||
using ifcopenshell::geom::opaque_number;
|
||||
|
||||
namespace {
|
||||
using Mesh = manifold::MeshGL64;
|
||||
using mesh_type = manifold::MeshGL64;
|
||||
|
||||
Mesh transform_mesh(const Mesh& mesh, const ifcopenshell::geometry::taxonomy::matrix4& place) {
|
||||
Mesh result = mesh;
|
||||
mesh_type transform_mesh(const mesh_type& mesh, const ifcopenshell::geom::taxonomy::matrix4& place) {
|
||||
mesh_type result = mesh;
|
||||
const auto& m = place.ccomponents();
|
||||
const bool flip = m.block<3, 3>(0, 0).determinant() < 0.;
|
||||
for (size_t i = 0; i < mesh.NumVert(); ++i) {
|
||||
@@ -41,7 +41,7 @@ namespace {
|
||||
return result;
|
||||
}
|
||||
|
||||
std::optional<manifold::Manifold> make_manifold(const Mesh& mesh) {
|
||||
std::optional<manifold::Manifold> make_manifold(const mesh_type& mesh) {
|
||||
manifold::Manifold solid(mesh);
|
||||
if (solid.Status() == manifold::Manifold::Error::NoError) {
|
||||
return solid;
|
||||
@@ -49,7 +49,7 @@ namespace {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
manifold::Box mesh_bbox(const Mesh& mesh) {
|
||||
manifold::Box mesh_bbox(const mesh_type& mesh) {
|
||||
if (!mesh.NumVert()) {
|
||||
return {};
|
||||
}
|
||||
@@ -79,7 +79,7 @@ namespace {
|
||||
return size[0] * size[1] * size[2];
|
||||
}
|
||||
|
||||
double triangle_area(const Mesh& mesh, size_t tri) {
|
||||
double triangle_area(const mesh_type& mesh, size_t tri) {
|
||||
auto idx = [&](int corner) { return mesh.triVerts[tri * 3 + corner]; };
|
||||
auto point = [&](uint32_t i) {
|
||||
return Eigen::Vector3d(
|
||||
@@ -93,7 +93,7 @@ namespace {
|
||||
return 0.5 * ((b - a).cross(c - a)).norm();
|
||||
}
|
||||
|
||||
double mesh_area(const Mesh& mesh) {
|
||||
double mesh_area(const mesh_type& mesh) {
|
||||
double area = 0.;
|
||||
for (size_t i = 0; i < mesh.NumTri(); ++i) {
|
||||
area += triangle_area(mesh, i);
|
||||
@@ -101,7 +101,7 @@ namespace {
|
||||
return area;
|
||||
}
|
||||
|
||||
double mesh_volume(const Mesh& mesh) {
|
||||
double mesh_volume(const mesh_type& mesh) {
|
||||
double volume = 0.;
|
||||
for (size_t i = 0; i < mesh.NumTri(); ++i) {
|
||||
auto idx = [&](int corner) { return mesh.triVerts[i * 3 + corner]; };
|
||||
@@ -119,14 +119,14 @@ namespace {
|
||||
return std::abs(volume);
|
||||
}
|
||||
|
||||
struct EdgeHash {
|
||||
struct edge_hash {
|
||||
size_t operator()(const std::pair<uint32_t, uint32_t>& edge) const {
|
||||
return std::hash<uint64_t>()((uint64_t(edge.first) << 32) ^ uint64_t(edge.second));
|
||||
}
|
||||
};
|
||||
|
||||
std::unordered_map<std::pair<uint32_t, uint32_t>, int, EdgeHash> count_edges(const Mesh& mesh) {
|
||||
std::unordered_map<std::pair<uint32_t, uint32_t>, int, EdgeHash> edges;
|
||||
std::unordered_map<std::pair<uint32_t, uint32_t>, int, edge_hash> count_edges(const mesh_type& mesh) {
|
||||
std::unordered_map<std::pair<uint32_t, uint32_t>, int, edge_hash> edges;
|
||||
for (size_t i = 0; i < mesh.NumTri(); ++i) {
|
||||
uint32_t tri[3] = {
|
||||
(uint32_t) mesh.triVerts[i * 3 + 0],
|
||||
@@ -145,7 +145,7 @@ namespace {
|
||||
return edges;
|
||||
}
|
||||
|
||||
double mesh_length(const Mesh& mesh) {
|
||||
double mesh_length(const mesh_type& mesh) {
|
||||
double length = 0.;
|
||||
auto edges = count_edges(mesh);
|
||||
for (const auto& pair : edges) {
|
||||
@@ -164,40 +164,40 @@ namespace {
|
||||
return length;
|
||||
}
|
||||
|
||||
int mesh_edges(const Mesh& mesh) {
|
||||
int mesh_edges(const mesh_type& mesh) {
|
||||
return (int)count_edges(mesh).size();
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::ManifoldPart make_part(const manifold::Manifold& solid) {
|
||||
ifcopenshell::geom::manifold_part make_part(const manifold::Manifold& solid) {
|
||||
return { solid.GetMeshGL64(), solid };
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::ManifoldPart make_box_part(const manifold::Box& box) {
|
||||
ifcopenshell::geom::manifold_part make_box_part(const manifold::Box& box) {
|
||||
const auto size = box.Size();
|
||||
auto solid = manifold::Manifold::Cube(manifold::vec3(size[0], size[1], size[2]), false).Translate(box.min);
|
||||
return make_part(solid);
|
||||
}
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::ManifoldShape::ManifoldShape(const manifold::Manifold& solid) {
|
||||
ifcopenshell::geom::manifold_shape::manifold_shape(const manifold::Manifold& solid) {
|
||||
auto copy = solid;
|
||||
auto with_normals = copy.CalculateNormals(3);
|
||||
parts_.push_back({with_normals.GetMeshGL64(), solid});
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::ManifoldShape::ManifoldShape(const ManifoldPart& part)
|
||||
ifcopenshell::geom::manifold_shape::manifold_shape(const manifold_part& part)
|
||||
: parts_{ part } {}
|
||||
|
||||
ifcopenshell::geometry::ManifoldShape::ManifoldShape(ManifoldPart&& part)
|
||||
ifcopenshell::geom::manifold_shape::manifold_shape(manifold_part&& part)
|
||||
: parts_{ std::move(part) } {}
|
||||
|
||||
ifcopenshell::geometry::ManifoldShape::ManifoldShape(const std::vector<ManifoldPart>& parts)
|
||||
ifcopenshell::geom::manifold_shape::manifold_shape(const std::vector<manifold_part>& parts)
|
||||
: parts_(parts) {}
|
||||
|
||||
ifcopenshell::geometry::ManifoldShape::ManifoldShape(std::vector<ManifoldPart>&& parts)
|
||||
ifcopenshell::geom::manifold_shape::manifold_shape(std::vector<manifold_part>&& parts)
|
||||
: parts_(std::move(parts)) {}
|
||||
|
||||
std::optional<manifold::Manifold> ifcopenshell::geometry::ManifoldShape::as_manifold() const {
|
||||
std::optional<manifold::Manifold> ifcopenshell::geom::manifold_shape::as_manifold() const {
|
||||
if (parts_.empty()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
@@ -215,7 +215,7 @@ std::optional<manifold::Manifold> ifcopenshell::geometry::ManifoldShape::as_mani
|
||||
return manifold::Manifold::BatchBoolean(solids, manifold::OpType::Add);
|
||||
}
|
||||
|
||||
void ifcopenshell::geometry::ManifoldShape::Triangulate(ifcopenshell::geometry::Settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int item_id, int surface_style_id, ::logger&) const {
|
||||
void ifcopenshell::geom::manifold_shape::Triangulate(ifcopenshell::geom::settings, const ifcopenshell::geom::taxonomy::matrix4& place, ifcopenshell::geom::Representation::triangulation* t, int item_id, int surface_style_id, ::logger&) const {
|
||||
for (const auto& part : parts_) {
|
||||
auto mesh = transform_mesh(part.mesh, place);
|
||||
std::vector<int> indices(mesh.NumVert());
|
||||
@@ -250,7 +250,7 @@ void ifcopenshell::geometry::ManifoldShape::Triangulate(ifcopenshell::geometry::
|
||||
}
|
||||
}
|
||||
|
||||
void ifcopenshell::geometry::ManifoldShape::Serialize(const ifcopenshell::geometry::taxonomy::matrix4& place, std::string& result) const {
|
||||
void ifcopenshell::geom::manifold_shape::Serialize(const ifcopenshell::geom::taxonomy::matrix4& place, std::string& result) const {
|
||||
std::stringstream stream;
|
||||
stream << std::setprecision(17);
|
||||
size_t offset = 0;
|
||||
@@ -273,7 +273,7 @@ void ifcopenshell::geometry::ManifoldShape::Serialize(const ifcopenshell::geomet
|
||||
result = stream.str();
|
||||
}
|
||||
|
||||
int ifcopenshell::geometry::ManifoldShape::surface_genus() const {
|
||||
int ifcopenshell::geom::manifold_shape::surface_genus() const {
|
||||
int genus = 0;
|
||||
for (const auto& part : parts_) {
|
||||
if (!part.solid) {
|
||||
@@ -284,11 +284,11 @@ int ifcopenshell::geometry::ManifoldShape::surface_genus() const {
|
||||
return genus;
|
||||
}
|
||||
|
||||
bool ifcopenshell::geometry::ManifoldShape::is_manifold() const {
|
||||
bool ifcopenshell::geom::manifold_shape::is_manifold() const {
|
||||
return std::all_of(parts_.begin(), parts_.end(), [](const auto& part) { return part.solid.has_value(); });
|
||||
}
|
||||
|
||||
int ifcopenshell::geometry::ManifoldShape::num_vertices() const {
|
||||
int ifcopenshell::geom::manifold_shape::num_vertices() const {
|
||||
size_t total = 0;
|
||||
for (const auto& part : parts_) {
|
||||
total += part.mesh.NumVert();
|
||||
@@ -296,7 +296,7 @@ int ifcopenshell::geometry::ManifoldShape::num_vertices() const {
|
||||
return (int)total;
|
||||
}
|
||||
|
||||
int ifcopenshell::geometry::ManifoldShape::num_edges() const {
|
||||
int ifcopenshell::geom::manifold_shape::num_edges() const {
|
||||
int total = 0;
|
||||
for (const auto& part : parts_) {
|
||||
total += part.solid ? (int)part.solid->NumEdge() : mesh_edges(part.mesh);
|
||||
@@ -304,7 +304,7 @@ int ifcopenshell::geometry::ManifoldShape::num_edges() const {
|
||||
return total;
|
||||
}
|
||||
|
||||
int ifcopenshell::geometry::ManifoldShape::num_faces() const {
|
||||
int ifcopenshell::geom::manifold_shape::num_faces() const {
|
||||
size_t total = 0;
|
||||
for (const auto& part : parts_) {
|
||||
total += part.solid ? part.solid->NumTri() : part.mesh.NumTri();
|
||||
@@ -312,7 +312,7 @@ int ifcopenshell::geometry::ManifoldShape::num_faces() const {
|
||||
return (int)total;
|
||||
}
|
||||
|
||||
double ifcopenshell::geometry::ManifoldShape::bounding_box(void*& box_ptr) const {
|
||||
double ifcopenshell::geom::manifold_shape::bounding_box(void*& box_ptr) const {
|
||||
bool initialized = false;
|
||||
auto* box = static_cast<manifold::Box*>(box_ptr);
|
||||
if (!box) {
|
||||
@@ -335,7 +335,7 @@ double ifcopenshell::geometry::ManifoldShape::bounding_box(void*& box_ptr) const
|
||||
return initialized ? bbox_volume(*box) : 0.;
|
||||
}
|
||||
|
||||
std::pair<OpaqueCoordinate<3>, OpaqueCoordinate<3>> ifcopenshell::geometry::ManifoldShape::bounding_box() const {
|
||||
std::pair<opaque_coordinate<3>, opaque_coordinate<3>> ifcopenshell::geom::manifold_shape::bounding_box() const {
|
||||
void* box_ptr = nullptr;
|
||||
bounding_box(box_ptr);
|
||||
auto* box = static_cast<manifold::Box*>(box_ptr);
|
||||
@@ -344,19 +344,19 @@ std::pair<OpaqueCoordinate<3>, OpaqueCoordinate<3>> ifcopenshell::geometry::Mani
|
||||
throw std::runtime_error("Invalid shape");
|
||||
}
|
||||
auto result = std::make_pair(
|
||||
OpaqueCoordinate<3>(
|
||||
OpaqueNumber(box->min[0]),
|
||||
OpaqueNumber(box->min[1]),
|
||||
OpaqueNumber(box->min[2])),
|
||||
OpaqueCoordinate<3>(
|
||||
OpaqueNumber(box->max[0]),
|
||||
OpaqueNumber(box->max[1]),
|
||||
OpaqueNumber(box->max[2])));
|
||||
opaque_coordinate<3>(
|
||||
opaque_number(box->min[0]),
|
||||
opaque_number(box->min[1]),
|
||||
opaque_number(box->min[2])),
|
||||
opaque_coordinate<3>(
|
||||
opaque_number(box->max[0]),
|
||||
opaque_number(box->max[1]),
|
||||
opaque_number(box->max[2])));
|
||||
delete box;
|
||||
return result;
|
||||
}
|
||||
|
||||
void ifcopenshell::geometry::ManifoldShape::set_box(void* box_ptr) {
|
||||
void ifcopenshell::geom::manifold_shape::set_box(void* box_ptr) {
|
||||
auto* box = static_cast<manifold::Box*>(box_ptr);
|
||||
if (!box || !box->IsFinite()) {
|
||||
throw std::runtime_error("Invalid shape");
|
||||
@@ -364,51 +364,51 @@ void ifcopenshell::geometry::ManifoldShape::set_box(void* box_ptr) {
|
||||
parts_ = { make_box_part(*box) };
|
||||
}
|
||||
|
||||
OpaqueNumber ifcopenshell::geometry::ManifoldShape::length() {
|
||||
opaque_number ifcopenshell::geom::manifold_shape::length() {
|
||||
double total = 0.;
|
||||
for (const auto& part : parts_) {
|
||||
total += mesh_length(part.mesh);
|
||||
}
|
||||
return OpaqueNumber(total);
|
||||
return opaque_number(total);
|
||||
}
|
||||
|
||||
OpaqueNumber ifcopenshell::geometry::ManifoldShape::area() {
|
||||
opaque_number ifcopenshell::geom::manifold_shape::area() {
|
||||
double total = 0.;
|
||||
for (const auto& part : parts_) {
|
||||
total += part.solid ? part.solid->SurfaceArea() : mesh_area(part.mesh);
|
||||
}
|
||||
return OpaqueNumber(total);
|
||||
return opaque_number(total);
|
||||
}
|
||||
|
||||
OpaqueNumber ifcopenshell::geometry::ManifoldShape::volume() {
|
||||
opaque_number ifcopenshell::geom::manifold_shape::volume() {
|
||||
double total = 0.;
|
||||
for (const auto& part : parts_) {
|
||||
total += part.solid ? part.solid->Volume() : mesh_volume(part.mesh);
|
||||
}
|
||||
return OpaqueNumber(total);
|
||||
return opaque_number(total);
|
||||
}
|
||||
|
||||
OpaqueCoordinate<3> ifcopenshell::geometry::ManifoldShape::position() {
|
||||
opaque_coordinate<3> ifcopenshell::geom::manifold_shape::position() {
|
||||
throw std::runtime_error("Invalid shape");
|
||||
}
|
||||
|
||||
OpaqueCoordinate<3> ifcopenshell::geometry::ManifoldShape::axis() {
|
||||
opaque_coordinate<3> ifcopenshell::geom::manifold_shape::axis() {
|
||||
throw std::runtime_error("Invalid shape");
|
||||
}
|
||||
|
||||
OpaqueCoordinate<4> ifcopenshell::geometry::ManifoldShape::plane_equation() {
|
||||
opaque_coordinate<4> ifcopenshell::geom::manifold_shape::plane_equation() {
|
||||
throw std::runtime_error("Invalid shape");
|
||||
}
|
||||
|
||||
std::vector<ConversionResultShape*> ifcopenshell::geometry::ManifoldShape::convex_decomposition() {
|
||||
std::vector<conversion_result_shape*> ifcopenshell::geom::manifold_shape::convex_decomposition() {
|
||||
throw std::runtime_error("Not implemented");
|
||||
}
|
||||
|
||||
ConversionResultShape* ifcopenshell::geometry::ManifoldShape::halfspaces() {
|
||||
conversion_result_shape* ifcopenshell::geom::manifold_shape::halfspaces() {
|
||||
throw std::runtime_error("Not implemented");
|
||||
}
|
||||
|
||||
ConversionResultShape* ifcopenshell::geometry::ManifoldShape::box() {
|
||||
conversion_result_shape* ifcopenshell::geom::manifold_shape::box() {
|
||||
void* box_ptr = nullptr;
|
||||
bounding_box(box_ptr);
|
||||
auto* box = static_cast<manifold::Box*>(box_ptr);
|
||||
@@ -416,36 +416,36 @@ ConversionResultShape* ifcopenshell::geometry::ManifoldShape::box() {
|
||||
delete box;
|
||||
throw std::runtime_error("Invalid shape");
|
||||
}
|
||||
auto* result = new ManifoldShape(make_box_part(*box));
|
||||
auto* result = new manifold_shape(make_box_part(*box));
|
||||
delete box;
|
||||
return result;
|
||||
}
|
||||
|
||||
ConversionResultShape* ifcopenshell::geometry::ManifoldShape::solid() {
|
||||
conversion_result_shape* ifcopenshell::geom::manifold_shape::solid() {
|
||||
if (!is_manifold()) {
|
||||
throw std::runtime_error("Invalid shape");
|
||||
}
|
||||
return new ManifoldShape(parts_);
|
||||
return new manifold_shape(parts_);
|
||||
}
|
||||
|
||||
ConversionResultShape* ifcopenshell::geometry::ManifoldShape::wrap_in_compound() {
|
||||
return new ManifoldShape(parts_);
|
||||
conversion_result_shape* ifcopenshell::geom::manifold_shape::wrap_in_compound() {
|
||||
return new manifold_shape(parts_);
|
||||
}
|
||||
|
||||
std::vector<ConversionResultShape*> ifcopenshell::geometry::ManifoldShape::vertices() {
|
||||
std::vector<conversion_result_shape*> ifcopenshell::geom::manifold_shape::vertices() {
|
||||
throw std::runtime_error("Not implemented");
|
||||
}
|
||||
|
||||
std::vector<ConversionResultShape*> ifcopenshell::geometry::ManifoldShape::edges() {
|
||||
std::vector<conversion_result_shape*> ifcopenshell::geom::manifold_shape::edges() {
|
||||
throw std::runtime_error("Not implemented");
|
||||
}
|
||||
|
||||
std::vector<ConversionResultShape*> ifcopenshell::geometry::ManifoldShape::facets() {
|
||||
std::vector<conversion_result_shape*> ifcopenshell::geom::manifold_shape::facets() {
|
||||
throw std::runtime_error("Not implemented");
|
||||
}
|
||||
|
||||
ConversionResultShape* ifcopenshell::geometry::ManifoldShape::add(ConversionResultShape* other) {
|
||||
auto* rhs = dynamic_cast<ManifoldShape*>(other);
|
||||
conversion_result_shape* ifcopenshell::geom::manifold_shape::add(conversion_result_shape* other) {
|
||||
auto* rhs = dynamic_cast<manifold_shape*>(other);
|
||||
if (!rhs) {
|
||||
throw std::runtime_error("Invalid shape");
|
||||
}
|
||||
@@ -454,11 +454,11 @@ ConversionResultShape* ifcopenshell::geometry::ManifoldShape::add(ConversionResu
|
||||
if (!a || !b) {
|
||||
throw std::runtime_error("Invalid shape");
|
||||
}
|
||||
return new ManifoldShape(make_part(*a + *b));
|
||||
return new manifold_shape(make_part(*a + *b));
|
||||
}
|
||||
|
||||
ConversionResultShape* ifcopenshell::geometry::ManifoldShape::subtract(ConversionResultShape* other) {
|
||||
auto* rhs = dynamic_cast<ManifoldShape*>(other);
|
||||
conversion_result_shape* ifcopenshell::geom::manifold_shape::subtract(conversion_result_shape* other) {
|
||||
auto* rhs = dynamic_cast<manifold_shape*>(other);
|
||||
if (!rhs) {
|
||||
throw std::runtime_error("Invalid shape");
|
||||
}
|
||||
@@ -467,11 +467,11 @@ ConversionResultShape* ifcopenshell::geometry::ManifoldShape::subtract(Conversio
|
||||
if (!a || !b) {
|
||||
throw std::runtime_error("Invalid shape");
|
||||
}
|
||||
return new ManifoldShape(make_part(*a - *b));
|
||||
return new manifold_shape(make_part(*a - *b));
|
||||
}
|
||||
|
||||
ConversionResultShape* ifcopenshell::geometry::ManifoldShape::intersect(ConversionResultShape* other) {
|
||||
auto* rhs = dynamic_cast<ManifoldShape*>(other);
|
||||
conversion_result_shape* ifcopenshell::geom::manifold_shape::intersect(conversion_result_shape* other) {
|
||||
auto* rhs = dynamic_cast<manifold_shape*>(other);
|
||||
if (!rhs) {
|
||||
throw std::runtime_error("Invalid shape");
|
||||
}
|
||||
@@ -480,29 +480,29 @@ ConversionResultShape* ifcopenshell::geometry::ManifoldShape::intersect(Conversi
|
||||
if (!a || !b) {
|
||||
throw std::runtime_error("Invalid shape");
|
||||
}
|
||||
return new ManifoldShape(make_part(*a ^ *b));
|
||||
return new manifold_shape(make_part(*a ^ *b));
|
||||
}
|
||||
|
||||
ConversionResultShape* ifcopenshell::geometry::ManifoldShape::concat(ConversionResultShape* other) {
|
||||
auto* rhs = dynamic_cast<ManifoldShape*>(other);
|
||||
conversion_result_shape* ifcopenshell::geom::manifold_shape::concat(conversion_result_shape* other) {
|
||||
auto* rhs = dynamic_cast<manifold_shape*>(other);
|
||||
if (!rhs) {
|
||||
throw std::runtime_error("Invalid shape");
|
||||
}
|
||||
auto parts = parts_;
|
||||
parts.insert(parts.end(), rhs->parts_.begin(), rhs->parts_.end());
|
||||
return new ManifoldShape(std::move(parts));
|
||||
return new manifold_shape(std::move(parts));
|
||||
}
|
||||
|
||||
std::size_t ifcopenshell::geometry::ManifoldShape::map(OpaqueCoordinate<4>&, OpaqueCoordinate<4>&) {
|
||||
std::size_t ifcopenshell::geom::manifold_shape::map(opaque_coordinate<4>&, opaque_coordinate<4>&) {
|
||||
throw std::runtime_error("Not implemented");
|
||||
}
|
||||
|
||||
std::size_t ifcopenshell::geometry::ManifoldShape::map(const std::vector<OpaqueCoordinate<4>>&, const std::vector<OpaqueCoordinate<4>>&) {
|
||||
std::size_t ifcopenshell::geom::manifold_shape::map(const std::vector<opaque_coordinate<4>>&, const std::vector<opaque_coordinate<4>>&) {
|
||||
throw std::runtime_error("Not implemented");
|
||||
}
|
||||
|
||||
ConversionResultShape* ifcopenshell::geometry::ManifoldShape::moved(ifcopenshell::geometry::taxonomy::matrix4::ptr place) const {
|
||||
std::vector<ManifoldPart> moved_parts;
|
||||
conversion_result_shape* ifcopenshell::geom::manifold_shape::moved(ifcopenshell::geom::taxonomy::matrix4::ptr place) const {
|
||||
std::vector<manifold_part> moved_parts;
|
||||
moved_parts.reserve(parts_.size());
|
||||
for (const auto& part : parts_) {
|
||||
auto mesh = transform_mesh(part.mesh, *place);
|
||||
@@ -512,10 +512,10 @@ ConversionResultShape* ifcopenshell::geometry::ManifoldShape::moved(ifcopenshell
|
||||
}
|
||||
moved_parts.emplace_back(mesh, *solid);
|
||||
}
|
||||
return new ManifoldShape(std::move(moved_parts));
|
||||
return new manifold_shape(std::move(moved_parts));
|
||||
}
|
||||
|
||||
bool ifcopenshell::geometry::ManifoldShape::surface_area_along_direction(double, const ifcopenshell::geometry::taxonomy::matrix4::ptr& place, double& along_x, double& along_y, double& along_z) const {
|
||||
bool ifcopenshell::geom::manifold_shape::surface_area_along_direction(double, const ifcopenshell::geom::taxonomy::matrix4::ptr& place, double& along_x, double& along_y, double& along_z) const {
|
||||
along_x = along_y = along_z = 0.;
|
||||
for (const auto& part : parts_) {
|
||||
auto mesh = transform_mesh(part.mesh, *place);
|
||||
|
||||
@@ -9,39 +9,39 @@
|
||||
#include <optional>
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace geometry {
|
||||
namespace geom {
|
||||
|
||||
struct IFC_GEOMLIBRARY_API ManifoldPart {
|
||||
struct IFC_GEOMLIBRARY_API manifold_part {
|
||||
manifold::MeshGL64 mesh;
|
||||
std::optional<manifold::Manifold> solid;
|
||||
|
||||
ManifoldPart(const manifold::Manifold& s) {
|
||||
manifold_part(const manifold::Manifold& s) {
|
||||
auto copy = s;
|
||||
copy.CalculateNormals(3);
|
||||
mesh = copy.GetMeshGL64();
|
||||
solid = s;
|
||||
}
|
||||
|
||||
ManifoldPart(const manifold::MeshGL64& s) : mesh(s) {}
|
||||
manifold_part(const manifold::MeshGL64& s) : mesh(s) {}
|
||||
|
||||
ManifoldPart(const manifold::MeshGL64& s, const manifold::Manifold& m) : mesh(s), solid(m) {}
|
||||
manifold_part(const manifold::MeshGL64& s, const manifold::Manifold& m) : mesh(s), solid(m) {}
|
||||
};
|
||||
|
||||
class IFC_GEOMLIBRARY_API ManifoldShape : public IfcGeom::ConversionResultShape {
|
||||
class IFC_GEOMLIBRARY_API manifold_shape : public ifcopenshell::geom::conversion_result_shape {
|
||||
public:
|
||||
ManifoldShape() = default;
|
||||
explicit ManifoldShape(const manifold::Manifold& part);
|
||||
explicit ManifoldShape(const ManifoldPart& part);
|
||||
explicit ManifoldShape(ManifoldPart&& part);
|
||||
explicit ManifoldShape(const std::vector<ManifoldPart>& parts);
|
||||
explicit ManifoldShape(std::vector<ManifoldPart>&& parts);
|
||||
manifold_shape() = default;
|
||||
explicit manifold_shape(const manifold::Manifold& part);
|
||||
explicit manifold_shape(const manifold_part& part);
|
||||
explicit manifold_shape(manifold_part&& part);
|
||||
explicit manifold_shape(const std::vector<manifold_part>& parts);
|
||||
explicit manifold_shape(std::vector<manifold_part>&& parts);
|
||||
|
||||
const std::vector<ManifoldPart>& parts() const { return parts_; }
|
||||
const std::vector<manifold_part>& parts() const { return parts_; }
|
||||
std::optional<manifold::Manifold> as_manifold() const;
|
||||
virtual std::string_view backend_id() const { return "manifold"; }
|
||||
|
||||
virtual void Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int item_id, int surface_style_id, ::logger& logger = ::logger::root()) const;
|
||||
virtual void Serialize(const ifcopenshell::geometry::taxonomy::matrix4& place, std::string&) const;
|
||||
virtual void Triangulate(ifcopenshell::geom::settings settings, const ifcopenshell::geom::taxonomy::matrix4& place, ifcopenshell::geom::Representation::triangulation* t, int item_id, int surface_style_id, ::logger& logger = ::logger::root()) const;
|
||||
virtual void Serialize(const ifcopenshell::geom::taxonomy::matrix4& place, std::string&) const;
|
||||
|
||||
virtual int surface_genus() const;
|
||||
virtual bool is_manifold() const;
|
||||
@@ -51,40 +51,40 @@ public:
|
||||
virtual int num_faces() const;
|
||||
|
||||
virtual double bounding_box(void*&) const;
|
||||
virtual std::pair<IfcGeom::OpaqueCoordinate<3>, IfcGeom::OpaqueCoordinate<3>> bounding_box() const;
|
||||
virtual std::pair<ifcopenshell::geom::opaque_coordinate<3>, ifcopenshell::geom::opaque_coordinate<3>> bounding_box() const;
|
||||
virtual void set_box(void* b);
|
||||
|
||||
virtual IfcGeom::OpaqueNumber length();
|
||||
virtual IfcGeom::OpaqueNumber area();
|
||||
virtual IfcGeom::OpaqueNumber volume();
|
||||
virtual ifcopenshell::geom::opaque_number length();
|
||||
virtual ifcopenshell::geom::opaque_number area();
|
||||
virtual ifcopenshell::geom::opaque_number volume();
|
||||
|
||||
virtual IfcGeom::OpaqueCoordinate<3> position();
|
||||
virtual IfcGeom::OpaqueCoordinate<3> axis();
|
||||
virtual IfcGeom::OpaqueCoordinate<4> plane_equation();
|
||||
virtual ifcopenshell::geom::opaque_coordinate<3> position();
|
||||
virtual ifcopenshell::geom::opaque_coordinate<3> axis();
|
||||
virtual ifcopenshell::geom::opaque_coordinate<4> plane_equation();
|
||||
|
||||
virtual std::vector<IfcGeom::ConversionResultShape*> convex_decomposition();
|
||||
virtual IfcGeom::ConversionResultShape* halfspaces();
|
||||
virtual IfcGeom::ConversionResultShape* box();
|
||||
virtual IfcGeom::ConversionResultShape* solid();
|
||||
virtual IfcGeom::ConversionResultShape* wrap_in_compound();
|
||||
virtual std::vector<ifcopenshell::geom::conversion_result_shape*> convex_decomposition();
|
||||
virtual ifcopenshell::geom::conversion_result_shape* halfspaces();
|
||||
virtual ifcopenshell::geom::conversion_result_shape* box();
|
||||
virtual ifcopenshell::geom::conversion_result_shape* solid();
|
||||
virtual ifcopenshell::geom::conversion_result_shape* wrap_in_compound();
|
||||
|
||||
virtual std::vector<IfcGeom::ConversionResultShape*> vertices();
|
||||
virtual std::vector<IfcGeom::ConversionResultShape*> edges();
|
||||
virtual std::vector<IfcGeom::ConversionResultShape*> facets();
|
||||
virtual std::vector<ifcopenshell::geom::conversion_result_shape*> vertices();
|
||||
virtual std::vector<ifcopenshell::geom::conversion_result_shape*> edges();
|
||||
virtual std::vector<ifcopenshell::geom::conversion_result_shape*> facets();
|
||||
|
||||
virtual IfcGeom::ConversionResultShape* add(IfcGeom::ConversionResultShape*);
|
||||
virtual IfcGeom::ConversionResultShape* subtract(IfcGeom::ConversionResultShape*);
|
||||
virtual IfcGeom::ConversionResultShape* intersect(IfcGeom::ConversionResultShape*);
|
||||
virtual IfcGeom::ConversionResultShape* concat(IfcGeom::ConversionResultShape*);
|
||||
virtual ifcopenshell::geom::conversion_result_shape* add(ifcopenshell::geom::conversion_result_shape*);
|
||||
virtual ifcopenshell::geom::conversion_result_shape* subtract(ifcopenshell::geom::conversion_result_shape*);
|
||||
virtual ifcopenshell::geom::conversion_result_shape* intersect(ifcopenshell::geom::conversion_result_shape*);
|
||||
virtual ifcopenshell::geom::conversion_result_shape* concat(ifcopenshell::geom::conversion_result_shape*);
|
||||
|
||||
virtual std::size_t map(IfcGeom::OpaqueCoordinate<4>& from, IfcGeom::OpaqueCoordinate<4>& to);
|
||||
virtual std::size_t map(const std::vector<IfcGeom::OpaqueCoordinate<4>>& from, const std::vector<IfcGeom::OpaqueCoordinate<4>>& to);
|
||||
virtual IfcGeom::ConversionResultShape* moved(ifcopenshell::geometry::taxonomy::matrix4::ptr) const;
|
||||
virtual std::size_t map(ifcopenshell::geom::opaque_coordinate<4>& from, ifcopenshell::geom::opaque_coordinate<4>& to);
|
||||
virtual std::size_t map(const std::vector<ifcopenshell::geom::opaque_coordinate<4>>& from, const std::vector<ifcopenshell::geom::opaque_coordinate<4>>& to);
|
||||
virtual ifcopenshell::geom::conversion_result_shape* moved(ifcopenshell::geom::taxonomy::matrix4::ptr) const;
|
||||
|
||||
virtual bool surface_area_along_direction(double tol, const ifcopenshell::geometry::taxonomy::matrix4::ptr&, double& along_x, double& along_y, double& along_z) const;
|
||||
virtual bool surface_area_along_direction(double tol, const ifcopenshell::geom::taxonomy::matrix4::ptr&, double& along_x, double& along_y, double& along_z) const;
|
||||
|
||||
private:
|
||||
std::vector<ManifoldPart> parts_;
|
||||
std::vector<manifold_part> parts_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -14,12 +14,12 @@
|
||||
#include <sstream>
|
||||
#include <unordered_map>
|
||||
|
||||
using namespace ifcopenshell::geometry;
|
||||
using namespace ifcopenshell::geometry::kernels;
|
||||
using namespace ifcopenshell::geom;
|
||||
using namespace ifcopenshell::geom::kernels;
|
||||
|
||||
namespace {
|
||||
using Mesh = manifold::MeshGL64;
|
||||
using Part = ifcopenshell::geometry::ManifoldPart;
|
||||
using mesh_type = manifold::MeshGL64;
|
||||
using part = ifcopenshell::geom::manifold_part;
|
||||
|
||||
std::string manifold_error_string(manifold::Manifold::Error error) {
|
||||
switch (error) {
|
||||
@@ -53,18 +53,18 @@ namespace {
|
||||
return "unknown error";
|
||||
}
|
||||
|
||||
struct VertexKey {
|
||||
struct vertex_key {
|
||||
long long x;
|
||||
long long y;
|
||||
long long z;
|
||||
|
||||
bool operator==(const VertexKey& other) const {
|
||||
bool operator==(const vertex_key& other) const {
|
||||
return x == other.x && y == other.y && z == other.z;
|
||||
}
|
||||
};
|
||||
|
||||
struct VertexKeyHash {
|
||||
size_t operator()(const VertexKey& key) const {
|
||||
struct vertex_key_hash {
|
||||
size_t operator()(const vertex_key& key) const {
|
||||
auto h = std::hash<long long>()(key.x);
|
||||
h ^= std::hash<long long>()(key.y) + 0x9e3779b97f4a7c15ull + (h << 6) + (h >> 2);
|
||||
h ^= std::hash<long long>()(key.z) + 0x9e3779b97f4a7c15ull + (h << 6) + (h >> 2);
|
||||
@@ -72,17 +72,17 @@ namespace {
|
||||
}
|
||||
};
|
||||
|
||||
struct MeshBuilder {
|
||||
struct mesh_builder {
|
||||
double precision;
|
||||
double dilation = 0.;
|
||||
std::vector<Eigen::Vector3d> vertices;
|
||||
std::unordered_map<VertexKey, uint64_t, VertexKeyHash> vertex_map;
|
||||
std::unordered_map<vertex_key, uint64_t, vertex_key_hash> vertex_map;
|
||||
std::vector<uint64_t> tri_verts;
|
||||
std::vector<uint64_t> face_ids;
|
||||
|
||||
explicit MeshBuilder(double p) : precision(p > 0. ? p : 1.e-9) {}
|
||||
explicit mesh_builder(double p) : precision(p > 0. ? p : 1.e-9) {}
|
||||
|
||||
VertexKey key(const Eigen::Vector3d& p) const {
|
||||
vertex_key key(const Eigen::Vector3d& p) const {
|
||||
return {
|
||||
(long long)std::llround(p(0) / precision),
|
||||
(long long)std::llround(p(1) / precision),
|
||||
@@ -111,8 +111,8 @@ namespace {
|
||||
face_ids.push_back(face_id);
|
||||
}
|
||||
|
||||
Mesh build() const {
|
||||
Mesh mesh;
|
||||
mesh_type build() const {
|
||||
mesh_type mesh;
|
||||
mesh.numProp = 3;
|
||||
|
||||
std::vector<size_t> vertex_use_count(vertices.size(), 0);
|
||||
@@ -149,42 +149,42 @@ namespace {
|
||||
}
|
||||
};
|
||||
|
||||
struct LoopPoint {
|
||||
struct loop_point {
|
||||
Eigen::Vector3d xyz;
|
||||
manifold::vec2 uv;
|
||||
};
|
||||
|
||||
using LoopPolygon = std::vector<LoopPoint>;
|
||||
using loop_polygon = std::vector<loop_point>;
|
||||
|
||||
struct EdgeKey {
|
||||
struct edge_key {
|
||||
uint64_t a;
|
||||
uint64_t b;
|
||||
|
||||
bool operator==(const EdgeKey& other) const {
|
||||
bool operator==(const edge_key& other) const {
|
||||
return a == other.a && b == other.b;
|
||||
}
|
||||
};
|
||||
|
||||
struct EdgeKeyHash {
|
||||
size_t operator()(const EdgeKey& key) const {
|
||||
struct edge_key_hash {
|
||||
size_t operator()(const edge_key& key) const {
|
||||
auto h = std::hash<uint64_t>()(key.a);
|
||||
h ^= std::hash<uint64_t>()(key.b) + 0x9e3779b97f4a7c15ull + (h << 6) + (h >> 2);
|
||||
return h;
|
||||
}
|
||||
};
|
||||
|
||||
struct FaceKey {
|
||||
struct face_key {
|
||||
uint64_t a;
|
||||
uint64_t b;
|
||||
uint64_t c;
|
||||
|
||||
bool operator==(const FaceKey& other) const {
|
||||
bool operator==(const face_key& other) const {
|
||||
return a == other.a && b == other.b && c == other.c;
|
||||
}
|
||||
};
|
||||
|
||||
struct FaceKeyHash {
|
||||
size_t operator()(const FaceKey& key) const {
|
||||
struct face_key_hash {
|
||||
size_t operator()(const face_key& key) const {
|
||||
auto h = std::hash<uint64_t>()(key.a);
|
||||
h ^= std::hash<uint64_t>()(key.b) + 0x9e3779b97f4a7c15ull + (h << 6) + (h >> 2);
|
||||
h ^= std::hash<uint64_t>()(key.c) + 0x9e3779b97f4a7c15ull + (h << 6) + (h >> 2);
|
||||
@@ -192,12 +192,12 @@ namespace {
|
||||
}
|
||||
};
|
||||
|
||||
struct EdgeUseCount {
|
||||
struct edge_use_count {
|
||||
size_t forward = 0;
|
||||
size_t reverse = 0;
|
||||
};
|
||||
|
||||
struct MeshDiagnostics {
|
||||
struct mesh_diagnostics {
|
||||
size_t vertices = 0;
|
||||
size_t triangles = 0;
|
||||
size_t unique_edges = 0;
|
||||
@@ -219,7 +219,7 @@ namespace {
|
||||
double max_area = 0.;
|
||||
};
|
||||
|
||||
struct ShellDiagnostics {
|
||||
struct shell_diagnostics {
|
||||
size_t faces = 0;
|
||||
size_t loops = 0;
|
||||
size_t edges = 0;
|
||||
@@ -399,10 +399,10 @@ namespace {
|
||||
}
|
||||
|
||||
bool append_extrusion_loop_points(const taxonomy::loop::ptr& loop, int circle_segments, double precision, std::vector<Eigen::Vector3d>& points);
|
||||
bool loop_polygon_from_points(const std::vector<Eigen::Vector3d>& points, const Eigen::Vector3d& origin, const Eigen::Vector3d& x, const Eigen::Vector3d& y, double precision, LoopPolygon& polygon);
|
||||
double signed_area(const LoopPolygon& polygon);
|
||||
bool loop_polygon_from_points(const std::vector<Eigen::Vector3d>& points, const Eigen::Vector3d& origin, const Eigen::Vector3d& x, const Eigen::Vector3d& y, double precision, loop_polygon& polygon);
|
||||
double signed_area(const loop_polygon& polygon);
|
||||
|
||||
bool extrusion_face_polygons(const taxonomy::face::ptr& face, int circle_segments, double precision, Eigen::Vector3d& origin, Eigen::Vector3d& x, Eigen::Vector3d& y, std::vector<LoopPolygon>& polygons, size_t& outer_index) {
|
||||
bool extrusion_face_polygons(const taxonomy::face::ptr& face, int circle_segments, double precision, Eigen::Vector3d& origin, Eigen::Vector3d& x, Eigen::Vector3d& y, std::vector<loop_polygon>& polygons, size_t& outer_index) {
|
||||
polygons.clear();
|
||||
outer_index = 0;
|
||||
if (!extrusion_face_supported(face)) {
|
||||
@@ -423,7 +423,7 @@ namespace {
|
||||
if (!basis_from_points(points, loop_origin, loop_x, loop_y)) {
|
||||
return false;
|
||||
}
|
||||
LoopPolygon polygon;
|
||||
loop_polygon polygon;
|
||||
if (!loop_polygon_from_points(points, loop_origin, loop_x, loop_y, precision, polygon)) {
|
||||
return false;
|
||||
}
|
||||
@@ -440,7 +440,7 @@ namespace {
|
||||
double outer_area = 0.;
|
||||
polygons.reserve(loops.size());
|
||||
for (const auto& points : loops) {
|
||||
LoopPolygon polygon;
|
||||
loop_polygon polygon;
|
||||
if (!loop_polygon_from_points(points, origin, x, y, precision, polygon)) {
|
||||
return false;
|
||||
}
|
||||
@@ -525,7 +525,7 @@ namespace {
|
||||
return 0.5 * area;
|
||||
}
|
||||
|
||||
Eigen::Vector3d mesh_vertex(const Mesh& mesh, size_t index) {
|
||||
Eigen::Vector3d mesh_vertex(const mesh_type& mesh, size_t index) {
|
||||
return Eigen::Vector3d(
|
||||
mesh.vertProperties[index * mesh.numProp + 0],
|
||||
mesh.vertProperties[index * mesh.numProp + 1],
|
||||
@@ -542,12 +542,12 @@ namespace {
|
||||
return "(" + format_number(value(0)) + ", " + format_number(value(1)) + ", " + format_number(value(2)) + ")";
|
||||
}
|
||||
|
||||
MeshDiagnostics diagnose_mesh(const Mesh& mesh, double precision) {
|
||||
MeshDiagnostics diagnostics;
|
||||
mesh_diagnostics diagnose_mesh(const mesh_type& mesh, double precision) {
|
||||
mesh_diagnostics diagnostics;
|
||||
diagnostics.vertices = mesh.NumVert();
|
||||
diagnostics.triangles = mesh.NumTri();
|
||||
std::unordered_map<EdgeKey, EdgeUseCount, EdgeKeyHash> edge_use_count;
|
||||
std::unordered_map<FaceKey, size_t, FaceKeyHash> face_use_count;
|
||||
std::unordered_map<edge_key, edge_use_count, edge_key_hash> edge_use_count;
|
||||
std::unordered_map<face_key, size_t, face_key_hash> face_use_count;
|
||||
for (size_t i = 0; i < diagnostics.vertices; ++i) {
|
||||
auto p = mesh_vertex(mesh, i);
|
||||
if (!std::isfinite(p(0)) || !std::isfinite(p(1)) || !std::isfinite(p(2))) {
|
||||
@@ -603,7 +603,7 @@ namespace {
|
||||
}
|
||||
std::array<uint64_t, 3> face = { a, b, c };
|
||||
std::sort(face.begin(), face.end());
|
||||
const FaceKey face_key{ face[0], face[1], face[2] };
|
||||
const face_key face_key{ face[0], face[1], face[2] };
|
||||
auto face_it = face_use_count.find(face_key);
|
||||
if (face_it == face_use_count.end()) {
|
||||
face_use_count.insert({ face_key, 1 });
|
||||
@@ -611,10 +611,10 @@ namespace {
|
||||
face_it->second++;
|
||||
diagnostics.duplicate_faces++;
|
||||
}
|
||||
std::array<EdgeKey, 3> edges = {
|
||||
EdgeKey{ std::min(a, b), std::max(a, b) },
|
||||
EdgeKey{ std::min(b, c), std::max(b, c) },
|
||||
EdgeKey{ std::min(c, a), std::max(c, a) }
|
||||
std::array<edge_key, 3> edges = {
|
||||
edge_key{ std::min(a, b), std::max(a, b) },
|
||||
edge_key{ std::min(b, c), std::max(b, c) },
|
||||
edge_key{ std::min(c, a), std::max(c, a) }
|
||||
};
|
||||
std::array<bool, 3> forward = {
|
||||
a < b,
|
||||
@@ -651,8 +651,8 @@ namespace {
|
||||
return diagnostics;
|
||||
}
|
||||
|
||||
ShellDiagnostics diagnose_shell(const taxonomy::shell::ptr& shell) {
|
||||
ShellDiagnostics diagnostics;
|
||||
shell_diagnostics diagnose_shell(const taxonomy::shell::ptr& shell) {
|
||||
shell_diagnostics diagnostics;
|
||||
diagnostics.faces = shell->children.size();
|
||||
for (const auto& face : shell->children) {
|
||||
diagnostics.max_loops_per_face = std::max(diagnostics.max_loops_per_face, face->children.size());
|
||||
@@ -678,7 +678,7 @@ namespace {
|
||||
return diagnostics;
|
||||
}
|
||||
|
||||
std::string mesh_diagnostics_string(const MeshDiagnostics& diagnostics) {
|
||||
std::string mesh_diagnostics_string(const mesh_diagnostics& diagnostics) {
|
||||
std::ostringstream ss;
|
||||
ss << "verts=" << diagnostics.vertices
|
||||
<< " tris=" << diagnostics.triangles
|
||||
@@ -711,7 +711,7 @@ namespace {
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string shell_diagnostics_string(const ShellDiagnostics& diagnostics) {
|
||||
std::string shell_diagnostics_string(const shell_diagnostics& diagnostics) {
|
||||
std::ostringstream ss;
|
||||
ss << "faces=" << diagnostics.faces
|
||||
<< " loops=" << diagnostics.loops
|
||||
@@ -738,7 +738,7 @@ namespace {
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string solid_shell_failure_diagnosis(const Part& part, const MeshDiagnostics& before, const MeshDiagnostics& after, manifold::Manifold::Error before_status, manifold::Manifold::Error after_status) {
|
||||
std::string solid_shell_failure_diagnosis(const part& part, const mesh_diagnostics& before, const mesh_diagnostics& after, manifold::Manifold::Error before_status, manifold::Manifold::Error after_status) {
|
||||
const bool before_problematic =
|
||||
!part.solid ||
|
||||
before_status != manifold::Manifold::Error::NoError ||
|
||||
@@ -765,7 +765,7 @@ namespace {
|
||||
return "shell looks clean before and after mesh inspection, issue may be in manifold validation details";
|
||||
}
|
||||
|
||||
void log_solid_shell_transform_failure(const taxonomy::shell::ptr& shell, const Part& before_part, const Mesh& after_mesh, const taxonomy::matrix4::ptr& place, double precision, manifold::Manifold::Error before_status, manifold::Manifold::Error after_status) {
|
||||
void log_solid_shell_transform_failure(const taxonomy::shell::ptr& shell, const part& before_part, const mesh_type& after_mesh, const taxonomy::matrix4::ptr& place, double precision, manifold::Manifold::Error before_status, manifold::Manifold::Error after_status) {
|
||||
const auto shell_info = diagnose_shell(shell);
|
||||
const auto before = diagnose_mesh(before_part.mesh, precision);
|
||||
const auto after = diagnose_mesh(after_mesh, precision);
|
||||
@@ -791,7 +791,7 @@ namespace {
|
||||
return 0.5 * area;
|
||||
}
|
||||
|
||||
double signed_area(const LoopPolygon& polygon) {
|
||||
double signed_area(const loop_polygon& polygon) {
|
||||
double area = 0.;
|
||||
for (size_t i = 0; i < polygon.size(); ++i) {
|
||||
const auto& a = polygon[i].uv;
|
||||
@@ -920,7 +920,7 @@ namespace {
|
||||
return points.size() >= 3;
|
||||
}
|
||||
|
||||
bool loop_polygon_from_points(const std::vector<Eigen::Vector3d>& points, const Eigen::Vector3d& origin, const Eigen::Vector3d& x, const Eigen::Vector3d& y, double precision, LoopPolygon& polygon) {
|
||||
bool loop_polygon_from_points(const std::vector<Eigen::Vector3d>& points, const Eigen::Vector3d& origin, const Eigen::Vector3d& x, const Eigen::Vector3d& y, double precision, loop_polygon& polygon) {
|
||||
polygon.clear();
|
||||
polygon.reserve(points.size());
|
||||
for (const auto& point : points) {
|
||||
@@ -942,7 +942,7 @@ namespace {
|
||||
return polygon.size() >= 3;
|
||||
}
|
||||
|
||||
bool append_simple_loop(const taxonomy::loop::ptr& loop, const Eigen::Vector3d& origin, const Eigen::Vector3d& x, const Eigen::Vector3d& y, double precision, LoopPolygon& polygon) {
|
||||
bool append_simple_loop(const taxonomy::loop::ptr& loop, const Eigen::Vector3d& origin, const Eigen::Vector3d& x, const Eigen::Vector3d& y, double precision, loop_polygon& polygon) {
|
||||
polygon.clear();
|
||||
polygon.reserve(loop->children.size());
|
||||
for (const auto& edge : loop->children) {
|
||||
@@ -974,11 +974,11 @@ namespace {
|
||||
return true;
|
||||
}
|
||||
|
||||
void reverse_loop(LoopPolygon& polygon) {
|
||||
void reverse_loop(loop_polygon& polygon) {
|
||||
std::reverse(polygon.begin(), polygon.end());
|
||||
}
|
||||
|
||||
void append_loop(const LoopPolygon& loop_polygon, MeshBuilder& builder, manifold::PolygonsIdx& polygons) {
|
||||
void append_loop(const loop_polygon& loop_polygon, mesh_builder& builder, manifold::PolygonsIdx& polygons) {
|
||||
manifold::SimplePolygonIdx polygon;
|
||||
polygon.reserve(loop_polygon.size());
|
||||
for (const auto& point : loop_polygon) {
|
||||
@@ -990,7 +990,7 @@ namespace {
|
||||
polygons.push_back(std::move(polygon));
|
||||
}
|
||||
|
||||
bool append_face(const taxonomy::face::ptr& face, MeshBuilder& builder, uint64_t face_id) {
|
||||
bool append_face(const taxonomy::face::ptr& face, mesh_builder& builder, uint64_t face_id) {
|
||||
if (!face_supported(face)) {
|
||||
return false;
|
||||
}
|
||||
@@ -1000,14 +1000,14 @@ namespace {
|
||||
if (!face_basis(face, origin, x, y)) {
|
||||
return false;
|
||||
}
|
||||
std::vector<LoopPolygon> loops;
|
||||
std::vector<loop_polygon> loops;
|
||||
loops.reserve(face->children.size());
|
||||
size_t outer_index = 0;
|
||||
double outer_area = 0.;
|
||||
manifold::PolygonsIdx polygons;
|
||||
polygons.reserve(face->children.size());
|
||||
for (const auto& loop : face->children) {
|
||||
LoopPolygon loop_polygon;
|
||||
loop_polygon loop_polygon;
|
||||
if (!append_simple_loop(loop, origin, x, y, builder.precision, loop_polygon)) {
|
||||
return false;
|
||||
}
|
||||
@@ -1034,8 +1034,8 @@ namespace {
|
||||
return !triangles.empty();
|
||||
}
|
||||
|
||||
bool shell_to_mesh(const taxonomy::shell::ptr& shell, double precision, Mesh& mesh, double dilation) {
|
||||
MeshBuilder builder(precision);
|
||||
bool shell_to_mesh(const taxonomy::shell::ptr& shell, double precision, mesh_type& mesh, double dilation) {
|
||||
mesh_builder builder(precision);
|
||||
builder.dilation = dilation;
|
||||
uint64_t face_id = 0;
|
||||
bool any = false;
|
||||
@@ -1052,7 +1052,7 @@ namespace {
|
||||
return mesh.NumTri() > 0;
|
||||
}
|
||||
|
||||
std::optional<Part> part_from_mesh(const Mesh& mesh, bool require_manifold, manifold::Manifold::Error* status_ptr = nullptr) {
|
||||
std::optional<part> part_from_mesh(const mesh_type& mesh, bool require_manifold, manifold::Manifold::Error* status_ptr = nullptr) {
|
||||
auto solid = std::optional<manifold::Manifold>{};
|
||||
manifold::Manifold candidate(mesh);
|
||||
auto status = candidate.Status();
|
||||
@@ -1071,16 +1071,16 @@ namespace {
|
||||
return mesh;
|
||||
}
|
||||
|
||||
std::optional<Part> part_from_shell(const taxonomy::shell::ptr& shell, double precision, double dilation, manifold::Manifold::Error* status_ptr = nullptr) {
|
||||
Mesh mesh;
|
||||
std::optional<part> part_from_shell(const taxonomy::shell::ptr& shell, double precision, double dilation, manifold::Manifold::Error* status_ptr = nullptr) {
|
||||
mesh_type mesh;
|
||||
if (!shell_to_mesh(shell, precision, mesh, dilation)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return part_from_mesh(mesh, false, status_ptr);
|
||||
}
|
||||
|
||||
Mesh transform_mesh(const Mesh& mesh, const taxonomy::matrix4::ptr& place);
|
||||
std::optional<Part> part_from_extrusion(const taxonomy::extrusion::ptr& extrusion, double precision, double dilation, int circle_segments);
|
||||
mesh_type transform_mesh(const mesh_type& mesh, const taxonomy::matrix4::ptr& place);
|
||||
std::optional<part> part_from_extrusion(const taxonomy::extrusion::ptr& extrusion, double precision, double dilation, int circle_segments);
|
||||
|
||||
Eigen::Matrix4d matrix_or_identity(const taxonomy::matrix4::ptr& matrix) {
|
||||
return matrix ? matrix->ccomponents() : Eigen::Matrix4d::Identity();
|
||||
@@ -1109,7 +1109,7 @@ namespace {
|
||||
return face;
|
||||
}
|
||||
|
||||
bool explicit_loop_polygon(const taxonomy::loop::ptr& loop, const Eigen::Matrix4d& transform, const Eigen::Vector3d& plane_origin, const Eigen::Vector3d& x, const Eigen::Vector3d& y, double precision, LoopPolygon& polygon) {
|
||||
bool explicit_loop_polygon(const taxonomy::loop::ptr& loop, const Eigen::Matrix4d& transform, const Eigen::Vector3d& plane_origin, const Eigen::Vector3d& x, const Eigen::Vector3d& y, double precision, loop_polygon& polygon) {
|
||||
polygon.clear();
|
||||
if (!loop || loop->children.size() < 3) {
|
||||
return false;
|
||||
@@ -1145,12 +1145,12 @@ namespace {
|
||||
};
|
||||
}
|
||||
|
||||
struct HalfspaceBuildState {
|
||||
struct halfspace_build_state {
|
||||
bool unchanged = false;
|
||||
double depth = 0.;
|
||||
};
|
||||
|
||||
std::optional<Part> part_from_polygon_extrusion(std::vector<LoopPolygon> polygons, size_t outer_index, const Eigen::Vector3d& plane_normal, const Eigen::Vector3d& direction, double depth, double precision, double dilation) {
|
||||
std::optional<part> part_from_polygon_extrusion(std::vector<loop_polygon> polygons, size_t outer_index, const Eigen::Vector3d& plane_normal, const Eigen::Vector3d& direction, double depth, double precision, double dilation) {
|
||||
if (depth < precision || polygons.empty() || outer_index >= polygons.size()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
@@ -1182,7 +1182,7 @@ namespace {
|
||||
return std::nullopt;
|
||||
}
|
||||
auto offset = dir * depth;
|
||||
MeshBuilder builder(precision);
|
||||
mesh_builder builder(precision);
|
||||
builder.dilation = dilation;
|
||||
std::vector<std::vector<uint64_t>> bottoms;
|
||||
std::vector<std::vector<uint64_t>> tops;
|
||||
@@ -1241,7 +1241,7 @@ namespace {
|
||||
return part_from_mesh(builder.build(), true);
|
||||
}
|
||||
|
||||
std::optional<Part> part_from_halfspace_solid(HalfspaceBuildState& state, const taxonomy::solid::ptr& solid, const taxonomy::face::ptr& face,const manifold::Box& reference_box, double precision, double dilation) {
|
||||
std::optional<part> part_from_halfspace_solid(halfspace_build_state& state, const taxonomy::solid::ptr& solid, const taxonomy::face::ptr& face,const manifold::Box& reference_box, double precision, double dilation) {
|
||||
|
||||
auto plane = taxonomy::cast<taxonomy::plane>(face->basis);
|
||||
|
||||
@@ -1255,7 +1255,7 @@ namespace {
|
||||
Eigen::Vector3d origin = transform.col(3).head<3>();
|
||||
|
||||
auto project_along_global_z = [&](const Eigen::Vector3d& p)
|
||||
-> std::optional<LoopPoint> {
|
||||
-> std::optional<loop_point> {
|
||||
Eigen::Vector3d hit;
|
||||
|
||||
if (std::abs(normal.z()) > precision) {
|
||||
@@ -1266,7 +1266,7 @@ namespace {
|
||||
}
|
||||
|
||||
const auto delta = hit - origin;
|
||||
return std::make_optional(LoopPoint{
|
||||
return std::make_optional(loop_point{
|
||||
hit,
|
||||
manifold::vec2(delta.dot(x), delta.dot(y))});
|
||||
};
|
||||
@@ -1300,7 +1300,7 @@ namespace {
|
||||
}
|
||||
const auto diagonal = Eigen::Vector3d(reference_box.max[0] - reference_box.min[0], reference_box.max[1] - reference_box.min[1], reference_box.max[2] - reference_box.min[2]).norm();
|
||||
const auto margin = std::max(precision * 100., diagonal * 1.e-6);
|
||||
LoopPolygon polygon;
|
||||
loop_polygon polygon;
|
||||
if (face->children.empty()) {
|
||||
polygon = {
|
||||
{ origin + x * (u_min - margin) + y * (v_min - margin), manifold::vec2(u_min - margin, v_min - margin) },
|
||||
@@ -1327,7 +1327,7 @@ namespace {
|
||||
return part_from_polygon_extrusion({std::move(polygon)}, 0, normal, extrusion_dir * -inside_sign, max_depth + margin, precision, dilation);
|
||||
}
|
||||
|
||||
std::optional<Part> part_from_extrusion(const taxonomy::extrusion::ptr& extrusion, double precision, double dilation, int circle_segments) {
|
||||
std::optional<part> part_from_extrusion(const taxonomy::extrusion::ptr& extrusion, double precision, double dilation, int circle_segments) {
|
||||
if (extrusion->depth < precision) {
|
||||
return std::nullopt;
|
||||
}
|
||||
@@ -1338,7 +1338,7 @@ namespace {
|
||||
Eigen::Vector3d origin;
|
||||
Eigen::Vector3d x;
|
||||
Eigen::Vector3d y;
|
||||
std::vector<LoopPolygon> polygons;
|
||||
std::vector<loop_polygon> polygons;
|
||||
size_t outer_index = 0;
|
||||
if (!extrusion_face_polygons(face, circle_segments, precision, origin, x, y, polygons, outer_index)) {
|
||||
return std::nullopt;
|
||||
@@ -1361,7 +1361,7 @@ namespace {
|
||||
Eigen::Vector3d origin;
|
||||
Eigen::Vector3d x;
|
||||
Eigen::Vector3d y;
|
||||
std::vector<LoopPolygon> polygons;
|
||||
std::vector<loop_polygon> polygons;
|
||||
size_t outer_index = 0;
|
||||
if (!extrusion_face_polygons(face, settings::CircleSegments::defaultvalue, precision, origin, x, y, polygons, outer_index)) {
|
||||
return false;
|
||||
@@ -1382,9 +1382,9 @@ namespace {
|
||||
return !polygons.empty();
|
||||
}
|
||||
|
||||
Mesh transform_mesh(const Mesh& mesh, const taxonomy::matrix4::ptr& place) {
|
||||
mesh_type transform_mesh(const mesh_type& mesh, const taxonomy::matrix4::ptr& place) {
|
||||
const auto& m = place->ccomponents();
|
||||
Mesh result = mesh;
|
||||
mesh_type result = mesh;
|
||||
const bool flip = m.block<3, 3>(0, 0).determinant() < 0.;
|
||||
for (size_t i = 0; i < mesh.NumVert(); ++i) {
|
||||
Eigen::Vector4d v(
|
||||
@@ -1406,7 +1406,7 @@ namespace {
|
||||
return result;
|
||||
}
|
||||
|
||||
taxonomy::style::ptr fallback_style(const taxonomy::geom_item::ptr& item, const IfcGeom::ConversionResults& results) {
|
||||
taxonomy::style::ptr fallback_style(const taxonomy::geom_item::ptr& item, const ifcopenshell::geom::conversion_results& results) {
|
||||
if (item->surface_style) {
|
||||
return item->surface_style;
|
||||
}
|
||||
@@ -1418,16 +1418,16 @@ namespace {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::optional<manifold::Manifold> result_to_manifold(const IfcGeom::ConversionResult& result) {
|
||||
auto moved = std::unique_ptr<IfcGeom::ConversionResultShape>(result.apply_transform());
|
||||
auto* shape = dynamic_cast<ifcopenshell::geometry::ManifoldShape*>(moved.get());
|
||||
std::optional<manifold::Manifold> result_to_manifold(const ifcopenshell::geom::conversion_result& result) {
|
||||
auto moved = std::unique_ptr<ifcopenshell::geom::conversion_result_shape>(result.apply_transform());
|
||||
auto* shape = dynamic_cast<ifcopenshell::geom::manifold_shape*>(moved.get());
|
||||
if (!shape) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return shape->as_manifold();
|
||||
}
|
||||
|
||||
std::optional<manifold::Manifold> results_to_operand(const IfcGeom::ConversionResults& results) {
|
||||
std::optional<manifold::Manifold> results_to_operand(const ifcopenshell::geom::conversion_results& results) {
|
||||
std::vector<manifold::Manifold> operands;
|
||||
for (const auto& result : results) {
|
||||
auto operand = result_to_manifold(result);
|
||||
@@ -1444,7 +1444,7 @@ namespace {
|
||||
return manifold::Manifold::BatchBoolean(operands, manifold::OpType::Add);
|
||||
}
|
||||
|
||||
std::optional<manifold::Box> results_bbox(const IfcGeom::ConversionResults& results) {
|
||||
std::optional<manifold::Box> results_bbox(const ifcopenshell::geom::conversion_results& results) {
|
||||
bool any = false;
|
||||
manifold::Box bbox;
|
||||
for (const auto& result : results) {
|
||||
@@ -1489,21 +1489,21 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
bool ManifoldKernel::convert_impl(const taxonomy::extrusion::ptr extrusion, IfcGeom::ConversionResults& results) {
|
||||
bool manifold_kernel::convert_impl(const taxonomy::extrusion::ptr extrusion, ifcopenshell::geom::conversion_results& results) {
|
||||
auto part = part_from_extrusion(extrusion, settings_.get<settings::Precision>().get(), dilation_hack, settings_.get<settings::CircleSegments>().get());
|
||||
if (!part) {
|
||||
::logger::root().warning("Manifold kernel: failed to convert extrusion, requires planar bounds with line, circle or ellipse edges", extrusion->instance);
|
||||
return false;
|
||||
}
|
||||
results.emplace_back(IfcGeom::ConversionResult(
|
||||
results.emplace_back(ifcopenshell::geom::conversion_result(
|
||||
extrusion->instance.id(),
|
||||
extrusion->matrix,
|
||||
new ifcopenshell::geometry::ManifoldShape(std::move(*part)),
|
||||
new ifcopenshell::geom::manifold_shape(std::move(*part)),
|
||||
extrusion->surface_style));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ManifoldKernel::convert_impl(const taxonomy::shell::ptr shell, IfcGeom::ConversionResults& results) {
|
||||
bool manifold_kernel::convert_impl(const taxonomy::shell::ptr shell, ifcopenshell::geom::conversion_results& results) {
|
||||
manifold::Manifold::Error status = manifold::Manifold::Error::NoError;
|
||||
auto part = part_from_shell(shell, settings_.get<settings::Precision>().get(), dilation_hack, &status);
|
||||
if (!part) {
|
||||
@@ -1513,15 +1513,15 @@ bool ManifoldKernel::convert_impl(const taxonomy::shell::ptr shell, IfcGeom::Con
|
||||
if (!part->solid) {
|
||||
::logger::root().notice("Manifold kernel: shell converted as mesh only (" + manifold_error_string(status) + ")", shell->instance);
|
||||
}
|
||||
results.emplace_back(IfcGeom::ConversionResult(
|
||||
results.emplace_back(ifcopenshell::geom::conversion_result(
|
||||
shell->instance.id(),
|
||||
shell->matrix,
|
||||
new ifcopenshell::geometry::ManifoldShape(std::move(*part)),
|
||||
new ifcopenshell::geom::manifold_shape(std::move(*part)),
|
||||
shell->surface_style));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ManifoldKernel::convert_impl(const taxonomy::solid::ptr solid, IfcGeom::ConversionResults& results) {
|
||||
bool manifold_kernel::convert_impl(const taxonomy::solid::ptr solid, ifcopenshell::geom::conversion_results& results) {
|
||||
std::vector<manifold::Manifold> shells;
|
||||
for (const auto& shell : solid->children) {
|
||||
const auto precision = settings_.get<settings::Precision>().get();
|
||||
@@ -1548,15 +1548,15 @@ bool ManifoldKernel::convert_impl(const taxonomy::solid::ptr solid, IfcGeom::Con
|
||||
for (size_t i = 1; i < shells.size(); ++i) {
|
||||
result -= shells[i];
|
||||
}
|
||||
results.emplace_back(IfcGeom::ConversionResult(
|
||||
results.emplace_back(ifcopenshell::geom::conversion_result(
|
||||
solid->instance.id(),
|
||||
solid->matrix,
|
||||
new ifcopenshell::geometry::ManifoldShape(result),
|
||||
new ifcopenshell::geom::manifold_shape(result),
|
||||
solid->surface_style));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ManifoldKernel::convert_impl(const taxonomy::boolean_result::ptr br, IfcGeom::ConversionResults& results) {
|
||||
bool manifold_kernel::convert_impl(const taxonomy::boolean_result::ptr br, ifcopenshell::geom::conversion_results& results) {
|
||||
std::vector<manifold::Manifold> operands;
|
||||
taxonomy::style::ptr style;
|
||||
std::optional<manifold::Box> first_bbox;
|
||||
@@ -1573,7 +1573,7 @@ bool ManifoldKernel::convert_impl(const taxonomy::boolean_result::ptr br, IfcGeo
|
||||
::logger::root().warning("Manifold kernel: cannot fit halfspace operand without a valid first operand bounds", child->instance);
|
||||
return false;
|
||||
}
|
||||
HalfspaceBuildState state;
|
||||
halfspace_build_state state;
|
||||
auto part = part_from_halfspace_solid(state, solid, face, *first_bbox, precision, dilation_hack);
|
||||
if (!part) {
|
||||
if (state.unchanged && br->operation == taxonomy::boolean_result::SUBTRACTION) {
|
||||
@@ -1592,8 +1592,8 @@ bool ManifoldKernel::convert_impl(const taxonomy::boolean_result::ptr br, IfcGeo
|
||||
style = child->surface_style;
|
||||
}
|
||||
} else {
|
||||
IfcGeom::ConversionResults converted;
|
||||
if (!AbstractKernel::convert(child, converted)) {
|
||||
ifcopenshell::geom::conversion_results converted;
|
||||
if (!abstract_kernel::convert(child, converted)) {
|
||||
::logger::root().warning("Manifold kernel: failed to convert boolean operand", child->instance);
|
||||
return false;
|
||||
}
|
||||
@@ -1626,15 +1626,15 @@ bool ManifoldKernel::convert_impl(const taxonomy::boolean_result::ptr br, IfcGeo
|
||||
::logger::root().warning("Manifold kernel: boolean operation produced no result", br->instance);
|
||||
return false;
|
||||
}
|
||||
results.emplace_back(IfcGeom::ConversionResult(
|
||||
results.emplace_back(ifcopenshell::geom::conversion_result(
|
||||
br->instance.id(),
|
||||
br->matrix,
|
||||
new ifcopenshell::geometry::ManifoldShape(*result),
|
||||
new ifcopenshell::geom::manifold_shape(*result),
|
||||
br->surface_style ? br->surface_style : style));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ManifoldKernel::convert_openings(const express::Base&, const std::vector<std::pair<taxonomy::ptr, taxonomy::matrix4>>& openings, const IfcGeom::ConversionResults& entity_shapes, const taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes) {
|
||||
bool manifold_kernel::convert_openings(const express::base&, const std::vector<std::pair<taxonomy::ptr, taxonomy::matrix4>>& openings, const ifcopenshell::geom::conversion_results& entity_shapes, const taxonomy::matrix4& entity_trsf, ifcopenshell::geom::conversion_results& cut_shapes) {
|
||||
std::vector<manifold::Manifold> opening_operands;
|
||||
auto entity_bbox = results_bbox(entity_shapes);
|
||||
if (!entity_bbox) {
|
||||
@@ -1644,14 +1644,14 @@ bool ManifoldKernel::convert_openings(const express::Base&, const std::vector<st
|
||||
dilation_hack = settings_.get<settings::Precision>().get() * 10.;
|
||||
for (const auto& opening : openings) {
|
||||
const auto relative = taxonomy::make<taxonomy::matrix4>(entity_trsf.ccomponents().inverse() * opening.second.ccomponents());
|
||||
IfcGeom::ConversionResults converted;
|
||||
if (!AbstractKernel::convert(opening.first, converted)) {
|
||||
ifcopenshell::geom::conversion_results converted;
|
||||
if (!abstract_kernel::convert(opening.first, converted)) {
|
||||
::logger::root().warning("Manifold kernel: failed to convert opening operand", opening.first->instance);
|
||||
return false;
|
||||
}
|
||||
for (const auto& result : converted) {
|
||||
auto moved = std::unique_ptr<IfcGeom::ConversionResultShape>(result.Shape()->moved(taxonomy::make<taxonomy::matrix4>(relative->ccomponents() * result.Placement()->ccomponents())));
|
||||
auto* shape = dynamic_cast<ifcopenshell::geometry::ManifoldShape*>(moved.get());
|
||||
auto moved = std::unique_ptr<ifcopenshell::geom::conversion_result_shape>(result.Shape()->moved(taxonomy::make<taxonomy::matrix4>(relative->ccomponents() * result.Placement()->ccomponents())));
|
||||
auto* shape = dynamic_cast<ifcopenshell::geom::manifold_shape*>(moved.get());
|
||||
if (!shape) {
|
||||
::logger::root().warning("Manifold kernel: opening result is not a manifold shape");
|
||||
return false;
|
||||
@@ -1676,9 +1676,9 @@ bool ManifoldKernel::convert_openings(const express::Base&, const std::vector<st
|
||||
return false;
|
||||
}
|
||||
auto result = *operand - opening_union;
|
||||
cut_shapes.emplace_back(IfcGeom::ConversionResult(
|
||||
cut_shapes.emplace_back(ifcopenshell::geom::conversion_result(
|
||||
entity_shape.ItemId(),
|
||||
new ifcopenshell::geometry::ManifoldShape(result),
|
||||
new ifcopenshell::geom::manifold_shape(result),
|
||||
entity_shape.StylePtr()));
|
||||
}
|
||||
return !cut_shapes.empty();
|
||||
|
||||
@@ -8,30 +8,30 @@
|
||||
#include "../../../ifcgeom/kernels/manifold/ManifoldConversionResult.h"
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace geometry {
|
||||
namespace geom {
|
||||
namespace kernels {
|
||||
|
||||
class IFC_GEOMLIBRARY_API ManifoldKernel : public AbstractKernel {
|
||||
class IFC_GEOMLIBRARY_API manifold_kernel : public abstract_kernel {
|
||||
public:
|
||||
ManifoldKernel(const Settings& settings, ::logger& logger = ::logger::root())
|
||||
: AbstractKernel("manifold", settings, logger) {}
|
||||
manifold_kernel(const ifcopenshell::geom::settings& settings, ::logger& logger = ::logger::root())
|
||||
: abstract_kernel("manifold", settings, logger) {}
|
||||
|
||||
virtual AbstractKernel* clone(::logger& logger) const {
|
||||
return new ManifoldKernel(settings(), logger);
|
||||
virtual abstract_kernel* clone(::logger& logger) const {
|
||||
return new manifold_kernel(settings(), logger);
|
||||
}
|
||||
|
||||
virtual bool supports_openings() const { return true; }
|
||||
virtual bool supports_boolean_operations() const { return true; }
|
||||
|
||||
virtual bool convert_impl(const taxonomy::extrusion::ptr, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const taxonomy::shell::ptr, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const taxonomy::solid::ptr, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const taxonomy::boolean_result::ptr, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const taxonomy::extrusion::ptr, ifcopenshell::geom::conversion_results&);
|
||||
virtual bool convert_impl(const taxonomy::shell::ptr, ifcopenshell::geom::conversion_results&);
|
||||
virtual bool convert_impl(const taxonomy::solid::ptr, ifcopenshell::geom::conversion_results&);
|
||||
virtual bool convert_impl(const taxonomy::boolean_result::ptr, ifcopenshell::geom::conversion_results&);
|
||||
|
||||
double dilation_hack = 0.;
|
||||
|
||||
virtual bool convert_openings(const express::Base& entity, const std::vector<std::pair<taxonomy::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
|
||||
const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes);
|
||||
virtual bool convert_openings(const express::base& entity, const std::vector<std::pair<taxonomy::ptr, ifcopenshell::geom::taxonomy::matrix4>>& openings,
|
||||
const ifcopenshell::geom::conversion_results& entity_shapes, const ifcopenshell::geom::taxonomy::matrix4& entity_trsf, ifcopenshell::geom::conversion_results& cut_shapes);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <boost/dll/alias.hpp>
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace geometry {
|
||||
namespace geom {
|
||||
namespace kernels {
|
||||
namespace manifold_plugin {
|
||||
|
||||
@@ -35,8 +35,8 @@ namespace ifcopenshell {
|
||||
return kernel_plugin_metadata("manifold");
|
||||
}
|
||||
|
||||
AbstractKernel* create_kernel(ifcopenshell::file*, Settings& settings) {
|
||||
return new ManifoldKernel(settings);
|
||||
abstract_kernel* create_kernel(ifcopenshell::file*, ifcopenshell::geom::settings& settings) {
|
||||
return new manifold_kernel(settings);
|
||||
}
|
||||
|
||||
void register_plugin(kernel_registry& registry, const plugin::module& module) {
|
||||
@@ -51,6 +51,6 @@ namespace ifcopenshell {
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geometry::kernels::manifold_plugin::plugin_abi, ifcopenshell_plugin_abi_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geometry::kernels::manifold_plugin::plugin_metadata, ifcopenshell_plugin_metadata_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geometry::kernels::manifold_plugin::register_plugin, ifcopenshell_register_kernel_plugin_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geom::kernels::manifold_plugin::plugin_abi, ifcopenshell_plugin_abi_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geom::kernels::manifold_plugin::plugin_metadata, ifcopenshell_plugin_metadata_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geom::kernels::manifold_plugin::register_plugin, ifcopenshell_register_kernel_plugin_v1)
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
#include <IntTools_FaceFace.hxx>
|
||||
#include "clash_utils.h"
|
||||
|
||||
namespace IfcGeom {
|
||||
namespace ifcopenshell::geom {
|
||||
namespace {
|
||||
|
||||
// Approximates the distance `other` protrudes into `volume` by finding the
|
||||
@@ -1349,9 +1349,9 @@ namespace IfcGeom {
|
||||
return ts_filtered;
|
||||
}
|
||||
|
||||
std::vector<T> select(const IfcGeom::BRepElement* elem, bool completely_within = false, double extend = -1.e-5) const {
|
||||
auto shp = (ifcopenshell::geometry::OpenCascadeShape*)elem->geometry().as_compound();
|
||||
TopoDS_Shape compound(std::move(((ifcopenshell::geometry::OpenCascadeShape*)shp)->shape()));
|
||||
std::vector<T> select(const ifcopenshell::geom::brep_element* elem, bool completely_within = false, double extend = -1.e-5) const {
|
||||
auto shp = (ifcopenshell::geom::open_cascade_shape*)elem->geometry().as_compound();
|
||||
TopoDS_Shape compound(std::move(((ifcopenshell::geom::open_cascade_shape*)shp)->shape()));
|
||||
delete shp;
|
||||
|
||||
const auto& m = elem->transformation().data()->ccomponents();
|
||||
@@ -1380,7 +1380,7 @@ namespace IfcGeom {
|
||||
TopoDS_Vertex v;
|
||||
if (extend > 0.) {
|
||||
BRep_Builder B;
|
||||
B.MakeVertex(v, p, Precision::Confusion());
|
||||
B.MakeVertex(v, p, ::Precision::Confusion());
|
||||
}
|
||||
|
||||
typename std::vector<T>::const_iterator it = ts.begin();
|
||||
@@ -1425,13 +1425,13 @@ namespace IfcGeom {
|
||||
std::unordered_map<T, std::vector<gp_Vec>> normals_;
|
||||
|
||||
// Temporary structures for H5
|
||||
std::vector<IfcGeom::TriangulationElement*> triangulation_elements_;
|
||||
std::map<express::Base, std::string> global_ids_;
|
||||
std::map<express::Base, std::string> names_;
|
||||
std::map<express::Base, ifcopenshell::geometry::taxonomy::matrix4::ptr> placements_;
|
||||
std::vector<ifcopenshell::geom::triangulation_element*> triangulation_elements_;
|
||||
std::map<express::base, std::string> global_ids_;
|
||||
std::map<express::base, std::string> names_;
|
||||
std::map<express::base, ifcopenshell::geom::taxonomy::matrix4::ptr> placements_;
|
||||
std::map<std::string, std::vector<double>> local_verts_;
|
||||
std::map<std::string, std::vector<int>> local_faces_;
|
||||
std::map<std::string, std::vector<ifcopenshell::geometry::taxonomy::style::ptr>> local_materials_;
|
||||
std::map<std::string, std::vector<ifcopenshell::geom::taxonomy::style::ptr>> local_materials_;
|
||||
std::map<std::string, std::vector<int>> local_material_ids_;
|
||||
|
||||
bool enable_face_styles_ = false;
|
||||
@@ -1465,44 +1465,44 @@ namespace IfcGeom {
|
||||
};
|
||||
}
|
||||
|
||||
class opencascade_tree : public impl::tree<express::Entity> {
|
||||
class opencascade_tree : public impl::tree<express::entity> {
|
||||
public:
|
||||
|
||||
opencascade_tree() {};
|
||||
|
||||
opencascade_tree(ifcopenshell::file& f) {
|
||||
add_file(f, ifcopenshell::geometry::Settings{});
|
||||
add_file(f, ifcopenshell::geom::settings{});
|
||||
}
|
||||
|
||||
opencascade_tree(ifcopenshell::file& f, ifcopenshell::geometry::Settings settings) {
|
||||
opencascade_tree(ifcopenshell::file& f, ifcopenshell::geom::settings settings) {
|
||||
add_file(f, settings);
|
||||
}
|
||||
|
||||
opencascade_tree(IfcGeom::Iterator& it) {
|
||||
opencascade_tree(ifcopenshell::geom::iterator& it) {
|
||||
add_file(it);
|
||||
}
|
||||
|
||||
void add_file(ifcopenshell::file& f, ifcopenshell::geometry::Settings settings) {
|
||||
ifcopenshell::geometry::Settings settings_ = settings;
|
||||
settings_.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
|
||||
settings_.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = true;
|
||||
settings_.get<ifcopenshell::geometry::settings::ReorientShells>().value = true;
|
||||
void add_file(ifcopenshell::file& f, ifcopenshell::geom::settings settings) {
|
||||
ifcopenshell::geom::settings settings_ = settings;
|
||||
settings_.get<ifcopenshell::geom::settings::IteratorOutput>().value = ifcopenshell::geom::settings::NATIVE;
|
||||
settings_.get<ifcopenshell::geom::settings::UseWorldCoords>().value = true;
|
||||
settings_.get<ifcopenshell::geom::settings::ReorientShells>().value = true;
|
||||
|
||||
IfcGeom::Iterator it(std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel>(new OpenCascadeKernel(settings_)), settings_, &f, {}, 1);
|
||||
ifcopenshell::geom::iterator it(std::unique_ptr<ifcopenshell::geom::kernels::abstract_kernel>(new open_cascade_kernel(settings_)), settings_, &f, {}, 1);
|
||||
|
||||
add_file(it);
|
||||
}
|
||||
|
||||
void add_file(IfcGeom::Iterator& it) {
|
||||
void add_file(ifcopenshell::geom::iterator& it) {
|
||||
if (it.initialize()) {
|
||||
do {
|
||||
add_element(dynamic_cast<IfcGeom::BRepElement*>(it.get()));
|
||||
add_element(dynamic_cast<ifcopenshell::geom::brep_element*>(it.get()));
|
||||
} while (it.next());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void apply_matrix_to_flat_verts(const std::vector<T>& flat_list, const ifcopenshell::geometry::taxonomy::matrix4::ptr& matrix, std::vector<T>& result) {
|
||||
void apply_matrix_to_flat_verts(const std::vector<T>& flat_list, const ifcopenshell::geom::taxonomy::matrix4::ptr& matrix, std::vector<T>& result) {
|
||||
Eigen::Vector3d vin;
|
||||
result.clear();
|
||||
result.reserve(flat_list.size());
|
||||
@@ -1547,7 +1547,7 @@ namespace IfcGeom {
|
||||
return dict.empty();
|
||||
}
|
||||
|
||||
void add_element(IfcGeom::TriangulationElement* elem) {
|
||||
void add_element(ifcopenshell::geom::triangulation_element* elem) {
|
||||
|
||||
Bnd_Box aabb;
|
||||
Bnd_OBB obb;
|
||||
@@ -1705,7 +1705,7 @@ namespace IfcGeom {
|
||||
gp_Vec dir1(v1_pnt, v2_pnt);
|
||||
gp_Vec dir2(v1_pnt, v3_pnt);
|
||||
gp_Vec cross_product = dir1.Crossed(dir2);
|
||||
if (cross_product.Magnitude() > Precision::Confusion()) {
|
||||
if (cross_product.Magnitude() > ::Precision::Confusion()) {
|
||||
#if OCC_VERSION_HEX >= 0x80000
|
||||
triangulation.Elements.Append(BVH_Vec4i(
|
||||
#else
|
||||
@@ -1744,12 +1744,12 @@ namespace IfcGeom {
|
||||
max_protrusions_[t] = std::min(std::min(obb.XHSize(), obb.YHSize()), obb.ZHSize()) * 2;
|
||||
}
|
||||
|
||||
void add_element(IfcGeom::BRepElement* elem) {
|
||||
void add_element(ifcopenshell::geom::brep_element* elem) {
|
||||
if (!elem) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto compound_generic = (ifcopenshell::geometry::OpenCascadeShape*)elem->geometry().as_compound();
|
||||
auto compound_generic = (ifcopenshell::geom::open_cascade_shape*)elem->geometry().as_compound();
|
||||
TopoDS_Shape compound(std::move(compound_generic->shape()));
|
||||
delete compound_generic;
|
||||
|
||||
@@ -1795,7 +1795,7 @@ namespace IfcGeom {
|
||||
return protrusion_distances_;
|
||||
}
|
||||
|
||||
std::vector<IfcGeom::ray_intersection_result> select_ray(const gp_Pnt& p0, const gp_Dir& d, double length = 1000.) const {
|
||||
std::vector<ifcopenshell::geom::ray_intersection_result> select_ray(const gp_Pnt& p0, const gp_Dir& d, double length = 1000.) const {
|
||||
gp_Pnt p1 = p0.XYZ() + d.XYZ() * length;
|
||||
auto E = BRepBuilderAPI_MakeEdge(p0, p1).Edge();
|
||||
Bnd_Box bb;
|
||||
@@ -1852,7 +1852,7 @@ namespace IfcGeom {
|
||||
enable_face_styles_ = b;
|
||||
}
|
||||
|
||||
const std::vector<ifcopenshell::geometry::taxonomy::style::ptr>& styles() const {
|
||||
const std::vector<ifcopenshell::geom::taxonomy::style::ptr>& styles() const {
|
||||
return styles_;
|
||||
}
|
||||
|
||||
@@ -1860,7 +1860,7 @@ namespace IfcGeom {
|
||||
typedef NCollection_DataMap<TopoDS_Shape, int, TopTools_ShapeMapHasher> face_style_map_t;
|
||||
|
||||
face_style_map_t face_styles_;
|
||||
std::vector<ifcopenshell::geometry::taxonomy::style::ptr> styles_;
|
||||
std::vector<ifcopenshell::geom::taxonomy::style::ptr> styles_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -29,9 +29,9 @@
|
||||
#include <TopTools_FormatVersion.hxx>
|
||||
#endif
|
||||
|
||||
using IfcGeom::OpaqueNumber;
|
||||
using IfcGeom::OpaqueCoordinate;
|
||||
using IfcGeom::ConversionResultShape;
|
||||
using ifcopenshell::geom::opaque_number;
|
||||
using ifcopenshell::geom::opaque_coordinate;
|
||||
using ifcopenshell::geom::conversion_result_shape;
|
||||
|
||||
namespace {
|
||||
// We bypass the conversion to gp_GTrsf, because it does not work
|
||||
@@ -46,31 +46,31 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::OpenCascadeShape::OpenCascadeShape(const TopoDS_Shape& shape)
|
||||
ifcopenshell::geom::open_cascade_shape::open_cascade_shape(const TopoDS_Shape& shape)
|
||||
: shape_(shape) {}
|
||||
|
||||
ifcopenshell::geometry::OpenCascadeShape::OpenCascadeShape(TopoDS_Shape&& shape)
|
||||
ifcopenshell::geom::open_cascade_shape::open_cascade_shape(TopoDS_Shape&& shape)
|
||||
: shape_(std::move(shape)) {}
|
||||
|
||||
const TopoDS_Shape& ifcopenshell::geometry::OpenCascadeShape::shape() const {
|
||||
const TopoDS_Shape& ifcopenshell::geom::open_cascade_shape::shape() const {
|
||||
return shape_;
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::OpenCascadeShape::operator const TopoDS_Shape& () {
|
||||
ifcopenshell::geom::open_cascade_shape::operator const TopoDS_Shape& () {
|
||||
return shape_;
|
||||
}
|
||||
|
||||
std::string_view ifcopenshell::geometry::OpenCascadeShape::backend_id() const {
|
||||
std::string_view ifcopenshell::geom::open_cascade_shape::backend_id() const {
|
||||
return "opencascade";
|
||||
}
|
||||
|
||||
IfcGeom::ConversionResultShape* ifcopenshell::geometry::OpenCascadeShape::clone() const {
|
||||
return new OpenCascadeShape(shape_);
|
||||
ifcopenshell::geom::conversion_result_shape* ifcopenshell::geom::open_cascade_shape::clone() const {
|
||||
return new open_cascade_shape(shape_);
|
||||
}
|
||||
|
||||
void ifcopenshell::geometry::OpenCascadeShape::Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int item_id, int surface_style_id, ::logger& logger) const {
|
||||
void ifcopenshell::geom::open_cascade_shape::Triangulate(ifcopenshell::geom::settings settings, const ifcopenshell::geom::taxonomy::matrix4& place, ifcopenshell::geom::Representation::triangulation* t, int item_id, int surface_style_id, ::logger& logger) const {
|
||||
|
||||
// @todo remove duplication with OpenCascadeKernel::convert(const taxonomy::matrix4::ptr matrix, gp_GTrsf& trsf);
|
||||
// @todo remove duplication with open_cascade_kernel::convert(const taxonomy::matrix4::ptr matrix, gp_GTrsf& trsf);
|
||||
// above can be static?
|
||||
|
||||
// A 3x3 matrix to rotate the vertex normals
|
||||
@@ -243,7 +243,7 @@ void ifcopenshell::geometry::OpenCascadeShape::Triangulate(ifcopenshell::geometr
|
||||
}
|
||||
|
||||
if (polyhedral_output_without_holes || polyhedral_output_with_holes) {
|
||||
auto loops = IfcGeom::util::find_boundary_loops(t->verts(), triangle_indices);
|
||||
auto loops = ifcopenshell::geom::util::find_boundary_loops(t->verts(), triangle_indices);
|
||||
if (polyhedral_output_without_holes) {
|
||||
if (!loops.empty() && !loops[0].empty()) {
|
||||
t->addFace(item_id, surface_style_id, loops[0]);
|
||||
@@ -257,7 +257,7 @@ void ifcopenshell::geometry::OpenCascadeShape::Triangulate(ifcopenshell::geometr
|
||||
}
|
||||
|
||||
if (!t->normals().empty() && settings.get<settings::GenerateUvs>().get()) {
|
||||
t->uvs_ref() = IfcGeom::Representation::Triangulation::box_project_uvs(t->verts(), t->normals());
|
||||
t->uvs_ref() = ifcopenshell::geom::Representation::triangulation::box_project_uvs(t->verts(), t->normals());
|
||||
}
|
||||
|
||||
if (num_faces == 0) {
|
||||
@@ -372,8 +372,8 @@ void ifcopenshell::geometry::OpenCascadeShape::Triangulate(ifcopenshell::geometr
|
||||
}
|
||||
}
|
||||
|
||||
void ifcopenshell::geometry::OpenCascadeShape::Serialize(const ifcopenshell::geometry::taxonomy::matrix4& place, std::string& r) const {
|
||||
auto s = IfcGeom::util::apply_transformation(shape_, place);
|
||||
void ifcopenshell::geom::open_cascade_shape::Serialize(const ifcopenshell::geom::taxonomy::matrix4& place, std::string& r) const {
|
||||
auto s = ifcopenshell::geom::util::apply_transformation(shape_, place);
|
||||
std::stringstream sstream;
|
||||
#if OCC_VERSION_HEX >= 0x70600
|
||||
BRepTools::Write(s, sstream, false, false, TopTools_FormatVersion_VERSION_2);
|
||||
@@ -383,90 +383,90 @@ void ifcopenshell::geometry::OpenCascadeShape::Serialize(const ifcopenshell::geo
|
||||
r = sstream.str();
|
||||
}
|
||||
|
||||
int ifcopenshell::geometry::OpenCascadeShape::surface_genus() const {
|
||||
return IfcGeom::util::surface_genus(shape_);
|
||||
int ifcopenshell::geom::open_cascade_shape::surface_genus() const {
|
||||
return ifcopenshell::geom::util::surface_genus(shape_);
|
||||
}
|
||||
|
||||
bool ifcopenshell::geometry::OpenCascadeShape::is_manifold() const {
|
||||
return IfcGeom::util::is_manifold(shape_);
|
||||
bool ifcopenshell::geom::open_cascade_shape::is_manifold() const {
|
||||
return ifcopenshell::geom::util::is_manifold(shape_);
|
||||
}
|
||||
|
||||
int ifcopenshell::geometry::OpenCascadeShape::num_vertices() const
|
||||
int ifcopenshell::geom::open_cascade_shape::num_vertices() const
|
||||
{
|
||||
return IfcGeom::util::count(shape_, TopAbs_VERTEX);
|
||||
return ifcopenshell::geom::util::count(shape_, TopAbs_VERTEX);
|
||||
}
|
||||
|
||||
int ifcopenshell::geometry::OpenCascadeShape::num_edges() const
|
||||
int ifcopenshell::geom::open_cascade_shape::num_edges() const
|
||||
{
|
||||
return IfcGeom::util::count(shape_, TopAbs_EDGE);
|
||||
return ifcopenshell::geom::util::count(shape_, TopAbs_EDGE);
|
||||
}
|
||||
|
||||
int ifcopenshell::geometry::OpenCascadeShape::num_faces() const
|
||||
int ifcopenshell::geom::open_cascade_shape::num_faces() const
|
||||
{
|
||||
return IfcGeom::util::count(shape_, TopAbs_FACE);
|
||||
return ifcopenshell::geom::util::count(shape_, TopAbs_FACE);
|
||||
}
|
||||
|
||||
OpaqueNumber ifcopenshell::geometry::OpenCascadeShape::OpenCascadeShape::length()
|
||||
opaque_number ifcopenshell::geom::open_cascade_shape::open_cascade_shape::length()
|
||||
{
|
||||
GProp_GProps prop;
|
||||
BRepGProp::LinearProperties(shape_, prop);
|
||||
double l = prop.Mass();
|
||||
return OpaqueNumber(l);
|
||||
return opaque_number(l);
|
||||
}
|
||||
|
||||
OpaqueNumber ifcopenshell::geometry::OpenCascadeShape::area()
|
||||
opaque_number ifcopenshell::geom::open_cascade_shape::area()
|
||||
{
|
||||
GProp_GProps prop;
|
||||
BRepGProp::SurfaceProperties(shape_, prop);
|
||||
double l = prop.Mass();
|
||||
return OpaqueNumber(l);
|
||||
return opaque_number(l);
|
||||
}
|
||||
|
||||
OpaqueNumber ifcopenshell::geometry::OpenCascadeShape::volume()
|
||||
opaque_number ifcopenshell::geom::open_cascade_shape::volume()
|
||||
{
|
||||
GProp_GProps prop;
|
||||
BRepGProp::VolumeProperties(shape_, prop);
|
||||
double l = prop.Mass();
|
||||
return OpaqueNumber(l);
|
||||
return opaque_number(l);
|
||||
}
|
||||
|
||||
#include <Geom_Plane.hxx>
|
||||
|
||||
OpaqueCoordinate<3> ifcopenshell::geometry::OpenCascadeShape::position()
|
||||
opaque_coordinate<3> ifcopenshell::geom::open_cascade_shape::position()
|
||||
{
|
||||
if (shape_.ShapeType() == TopAbs_FACE) {
|
||||
auto surf = BRep_Tool::Surface(TopoDS::Face(shape_));
|
||||
auto plane = Handle(Geom_Plane)::DownCast(surf);
|
||||
if (plane) {
|
||||
auto loc = plane->Location();
|
||||
return OpaqueCoordinate<3>(
|
||||
OpaqueNumber(loc.X()),
|
||||
OpaqueNumber(loc.Y()),
|
||||
OpaqueNumber(loc.Z())
|
||||
return opaque_coordinate<3>(
|
||||
opaque_number(loc.X()),
|
||||
opaque_number(loc.Y()),
|
||||
opaque_number(loc.Z())
|
||||
);
|
||||
}
|
||||
}
|
||||
throw std::runtime_error("Invalid shape type");
|
||||
}
|
||||
|
||||
OpaqueCoordinate<3> ifcopenshell::geometry::OpenCascadeShape::axis()
|
||||
opaque_coordinate<3> ifcopenshell::geom::open_cascade_shape::axis()
|
||||
{
|
||||
if (shape_.ShapeType() == TopAbs_FACE) {
|
||||
auto surf = BRep_Tool::Surface(TopoDS::Face(shape_));
|
||||
auto plane = Handle(Geom_Plane)::DownCast(surf);
|
||||
if (plane) {
|
||||
auto dir = plane->Axis().Direction();
|
||||
return OpaqueCoordinate<3>(
|
||||
OpaqueNumber(dir.X()),
|
||||
OpaqueNumber(dir.Y()),
|
||||
OpaqueNumber(dir.Z())
|
||||
return opaque_coordinate<3>(
|
||||
opaque_number(dir.X()),
|
||||
opaque_number(dir.Y()),
|
||||
opaque_number(dir.Z())
|
||||
);
|
||||
}
|
||||
}
|
||||
throw std::runtime_error("Invalid shape type");
|
||||
}
|
||||
|
||||
OpaqueCoordinate<4> ifcopenshell::geometry::OpenCascadeShape::plane_equation()
|
||||
opaque_coordinate<4> ifcopenshell::geom::open_cascade_shape::plane_equation()
|
||||
{
|
||||
if (shape_.ShapeType() == TopAbs_FACE) {
|
||||
auto surf = BRep_Tool::Surface(TopoDS::Face(shape_));
|
||||
@@ -474,121 +474,121 @@ OpaqueCoordinate<4> ifcopenshell::geometry::OpenCascadeShape::plane_equation()
|
||||
if (plane) {
|
||||
double a, b, c, d;
|
||||
plane->Pln().Coefficients(a, b, c, d);
|
||||
return OpaqueCoordinate<4>(
|
||||
OpaqueNumber(a),
|
||||
OpaqueNumber(b),
|
||||
OpaqueNumber(c),
|
||||
OpaqueNumber(d)
|
||||
return opaque_coordinate<4>(
|
||||
opaque_number(a),
|
||||
opaque_number(b),
|
||||
opaque_number(c),
|
||||
opaque_number(d)
|
||||
);
|
||||
}
|
||||
}
|
||||
throw std::runtime_error("Invalid shape type");
|
||||
}
|
||||
|
||||
std::vector<ConversionResultShape*> ifcopenshell::geometry::OpenCascadeShape::convex_decomposition()
|
||||
std::vector<conversion_result_shape*> ifcopenshell::geom::open_cascade_shape::convex_decomposition()
|
||||
{
|
||||
throw std::runtime_error("Not implemented");
|
||||
}
|
||||
|
||||
ConversionResultShape * ifcopenshell::geometry::OpenCascadeShape::halfspaces()
|
||||
conversion_result_shape * ifcopenshell::geom::open_cascade_shape::halfspaces()
|
||||
{
|
||||
throw std::runtime_error("Not implemented");
|
||||
}
|
||||
|
||||
ConversionResultShape* ifcopenshell::geometry::OpenCascadeShape::solid()
|
||||
conversion_result_shape* ifcopenshell::geom::open_cascade_shape::solid()
|
||||
{
|
||||
throw std::runtime_error("Not implemented");
|
||||
}
|
||||
|
||||
ConversionResultShape * ifcopenshell::geometry::OpenCascadeShape::box()
|
||||
conversion_result_shape * ifcopenshell::geom::open_cascade_shape::box()
|
||||
{
|
||||
throw std::runtime_error("Not implemented");
|
||||
}
|
||||
|
||||
ConversionResultShape* ifcopenshell::geometry::OpenCascadeShape::wrap_in_compound()
|
||||
conversion_result_shape* ifcopenshell::geom::open_cascade_shape::wrap_in_compound()
|
||||
{
|
||||
TopoDS_Compound compound;
|
||||
BRep_Builder builder;
|
||||
builder.MakeCompound(compound);
|
||||
builder.Add(compound, shape_);
|
||||
return new OpenCascadeShape(std::move(compound));
|
||||
return new open_cascade_shape(std::move(compound));
|
||||
}
|
||||
|
||||
std::vector<ConversionResultShape*> ifcopenshell::geometry::OpenCascadeShape::vertices()
|
||||
std::vector<conversion_result_shape*> ifcopenshell::geom::open_cascade_shape::vertices()
|
||||
{
|
||||
NCollection_IndexedMap<TopoDS_Shape, TopTools_ShapeMapHasher> map;
|
||||
TopExp::MapShapes(shape_, TopAbs_VERTEX, map);
|
||||
std::vector<ConversionResultShape*> vec;
|
||||
std::vector<conversion_result_shape*> vec;
|
||||
for (int i = 1; i <= map.Extent(); ++i) {
|
||||
vec.push_back(new OpenCascadeShape(map.FindKey(i)));
|
||||
vec.push_back(new open_cascade_shape(map.FindKey(i)));
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
std::vector<ConversionResultShape*> ifcopenshell::geometry::OpenCascadeShape::edges()
|
||||
std::vector<conversion_result_shape*> ifcopenshell::geom::open_cascade_shape::edges()
|
||||
{
|
||||
NCollection_IndexedMap<TopoDS_Shape, TopTools_ShapeMapHasher> map;
|
||||
TopExp::MapShapes(shape_, TopAbs_EDGE, map);
|
||||
std::vector<ConversionResultShape*> vec;
|
||||
std::vector<conversion_result_shape*> vec;
|
||||
for (int i = 1; i <= map.Extent(); ++i) {
|
||||
vec.push_back(new OpenCascadeShape(map.FindKey(i)));
|
||||
vec.push_back(new open_cascade_shape(map.FindKey(i)));
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
std::vector<ConversionResultShape*> ifcopenshell::geometry::OpenCascadeShape::facets()
|
||||
std::vector<conversion_result_shape*> ifcopenshell::geom::open_cascade_shape::facets()
|
||||
{
|
||||
NCollection_IndexedMap<TopoDS_Shape, TopTools_ShapeMapHasher> map;
|
||||
TopExp::MapShapes(shape_, TopAbs_FACE, map);
|
||||
std::vector<ConversionResultShape*> vec;
|
||||
std::vector<conversion_result_shape*> vec;
|
||||
for (int i = 1; i <= map.Extent(); ++i) {
|
||||
vec.push_back(new OpenCascadeShape(map.FindKey(i)));
|
||||
vec.push_back(new open_cascade_shape(map.FindKey(i)));
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
namespace {
|
||||
ConversionResultShape* boolean_op(BOPAlgo_Operation op, const TopoDS_Shape& shape_, const TopoDS_Shape& other_shape) {
|
||||
IfcGeom::util::boolean_settings st;
|
||||
conversion_result_shape* boolean_op(BOPAlgo_Operation op, const TopoDS_Shape& shape_, const TopoDS_Shape& other_shape) {
|
||||
ifcopenshell::geom::util::boolean_settings st;
|
||||
st.attempt_2d = true;
|
||||
st.debug = false;
|
||||
st.precision = 1.e-5;
|
||||
|
||||
TopoDS_Shape result;
|
||||
if (IfcGeom::util::boolean_operation(st, shape_, other_shape, op, result)) {
|
||||
return new ifcopenshell::geometry::OpenCascadeShape(result);
|
||||
if (ifcopenshell::geom::util::boolean_operation(st, shape_, other_shape, op, result)) {
|
||||
return new ifcopenshell::geom::open_cascade_shape(result);
|
||||
} else {
|
||||
throw std::runtime_error("Failed to process boolean operation");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConversionResultShape* ifcopenshell::geometry::OpenCascadeShape::add(ConversionResultShape* other)
|
||||
conversion_result_shape* ifcopenshell::geom::open_cascade_shape::add(conversion_result_shape* other)
|
||||
{
|
||||
return boolean_op(BOPAlgo_FUSE, shape_, ((ifcopenshell::geometry::OpenCascadeShape*)other)->shape_);
|
||||
return boolean_op(BOPAlgo_FUSE, shape_, ((ifcopenshell::geom::open_cascade_shape*)other)->shape_);
|
||||
}
|
||||
|
||||
ConversionResultShape* ifcopenshell::geometry::OpenCascadeShape::subtract(ConversionResultShape* other)
|
||||
conversion_result_shape* ifcopenshell::geom::open_cascade_shape::subtract(conversion_result_shape* other)
|
||||
{
|
||||
return boolean_op(BOPAlgo_CUT, shape_, ((ifcopenshell::geometry::OpenCascadeShape*)other)->shape_);
|
||||
return boolean_op(BOPAlgo_CUT, shape_, ((ifcopenshell::geom::open_cascade_shape*)other)->shape_);
|
||||
}
|
||||
|
||||
ConversionResultShape* ifcopenshell::geometry::OpenCascadeShape::intersect(ConversionResultShape* other)
|
||||
conversion_result_shape* ifcopenshell::geom::open_cascade_shape::intersect(conversion_result_shape* other)
|
||||
{
|
||||
return boolean_op(BOPAlgo_COMMON, shape_, ((ifcopenshell::geometry::OpenCascadeShape*)other)->shape_);
|
||||
return boolean_op(BOPAlgo_COMMON, shape_, ((ifcopenshell::geom::open_cascade_shape*)other)->shape_);
|
||||
}
|
||||
|
||||
ConversionResultShape* ifcopenshell::geometry::OpenCascadeShape::concat(ConversionResultShape* other)
|
||||
conversion_result_shape* ifcopenshell::geom::open_cascade_shape::concat(conversion_result_shape* other)
|
||||
{
|
||||
TopoDS_Compound compound;
|
||||
BRep_Builder builder;
|
||||
|
||||
auto& left = shape_;
|
||||
auto& right = ((ifcopenshell::geometry::OpenCascadeShape*)other)->shape_;
|
||||
auto& right = ((ifcopenshell::geom::open_cascade_shape*)other)->shape_;
|
||||
|
||||
// This reads a bit strange, but we want to specifically avoid compounds of faces that are
|
||||
// the result of shell instances that are not sewn into a shell (yet).
|
||||
if (left.ShapeType() == TopAbs_COMPOUND && !IfcGeom::util::is_compound_of_faces(left)) {
|
||||
if (left.ShapeType() == TopAbs_COMPOUND && !ifcopenshell::geom::util::is_compound_of_faces(left)) {
|
||||
compound = TopoDS::Compound(left);
|
||||
} else {
|
||||
builder.MakeCompound(compound);
|
||||
@@ -597,17 +597,17 @@ ConversionResultShape* ifcopenshell::geometry::OpenCascadeShape::concat(Conversi
|
||||
|
||||
builder.Add(compound, right);
|
||||
|
||||
return new OpenCascadeShape(std::move(compound));
|
||||
return new open_cascade_shape(std::move(compound));
|
||||
}
|
||||
|
||||
std::pair<OpaqueCoordinate<3>, OpaqueCoordinate<3>> ifcopenshell::geometry::OpenCascadeShape::bounding_box() const
|
||||
std::pair<opaque_coordinate<3>, opaque_coordinate<3>> ifcopenshell::geom::open_cascade_shape::bounding_box() const
|
||||
{
|
||||
throw std::runtime_error("Not implemented");
|
||||
}
|
||||
|
||||
ConversionResultShape* ifcopenshell::geometry::OpenCascadeShape::moved(ifcopenshell::geometry::taxonomy::matrix4::ptr t) const
|
||||
conversion_result_shape* ifcopenshell::geom::open_cascade_shape::moved(ifcopenshell::geom::taxonomy::matrix4::ptr t) const
|
||||
{
|
||||
return new OpenCascadeShape(IfcGeom::util::apply_transformation(shape_, *t));
|
||||
return new open_cascade_shape(ifcopenshell::geom::util::apply_transformation(shape_, *t));
|
||||
}
|
||||
|
||||
namespace {
|
||||
@@ -694,7 +694,7 @@ namespace {
|
||||
}
|
||||
|
||||
|
||||
bool ifcopenshell::geometry::OpenCascadeShape::surface_area_along_direction(double tol, const ifcopenshell::geometry::taxonomy::matrix4::ptr& place, double& along_x, double& along_y, double& along_z) const
|
||||
bool ifcopenshell::geom::open_cascade_shape::surface_area_along_direction(double tol, const ifcopenshell::geom::taxonomy::matrix4::ptr& place, double& along_x, double& along_y, double& along_z) const
|
||||
{
|
||||
gp_GTrsf trsf;
|
||||
|
||||
@@ -717,10 +717,10 @@ bool ifcopenshell::geometry::OpenCascadeShape::surface_area_along_direction(doub
|
||||
return true;
|
||||
}
|
||||
|
||||
std::size_t ifcopenshell::geometry::OpenCascadeShape::map(OpaqueCoordinate<4>&, OpaqueCoordinate<4>&) {
|
||||
std::size_t ifcopenshell::geom::open_cascade_shape::map(opaque_coordinate<4>&, opaque_coordinate<4>&) {
|
||||
throw std::runtime_error("Not implemented");
|
||||
}
|
||||
|
||||
std::size_t ifcopenshell::geometry::OpenCascadeShape::map(const std::vector<OpaqueCoordinate<4>>&, const std::vector<OpaqueCoordinate<4>>&) {
|
||||
std::size_t ifcopenshell::geom::open_cascade_shape::map(const std::vector<opaque_coordinate<4>>&, const std::vector<opaque_coordinate<4>>&) {
|
||||
throw std::runtime_error("Not implemented");
|
||||
}
|
||||
|
||||
@@ -35,24 +35,24 @@
|
||||
#include "../../../ifcgeom/kernels/ifc_geomlibrary_api.h"
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace geometry {
|
||||
namespace geom {
|
||||
|
||||
using IfcGeom::OpaqueCoordinate;
|
||||
using IfcGeom::OpaqueNumber;
|
||||
using ifcopenshell::geom::opaque_coordinate;
|
||||
using ifcopenshell::geom::opaque_number;
|
||||
|
||||
class IFC_GEOMLIBRARY_API OpenCascadeShape : public IfcGeom::ConversionResultShape {
|
||||
class IFC_GEOMLIBRARY_API open_cascade_shape : public ifcopenshell::geom::conversion_result_shape {
|
||||
public:
|
||||
OpenCascadeShape(const TopoDS_Shape& shape);
|
||||
OpenCascadeShape(TopoDS_Shape&& shape);
|
||||
open_cascade_shape(const TopoDS_Shape& shape);
|
||||
open_cascade_shape(TopoDS_Shape&& shape);
|
||||
|
||||
const TopoDS_Shape& shape() const;
|
||||
operator const TopoDS_Shape& ();
|
||||
virtual std::string_view backend_id() const;
|
||||
|
||||
virtual void Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int item_id, int surface_style_id, ::logger& logger = ::logger::root()) const;
|
||||
virtual void Serialize(const ifcopenshell::geometry::taxonomy::matrix4& place, std::string&) const;
|
||||
virtual void Triangulate(ifcopenshell::geom::settings settings, const ifcopenshell::geom::taxonomy::matrix4& place, ifcopenshell::geom::Representation::triangulation* t, int item_id, int surface_style_id, ::logger& logger = ::logger::root()) const;
|
||||
virtual void Serialize(const ifcopenshell::geom::taxonomy::matrix4& place, std::string&) const;
|
||||
|
||||
virtual IfcGeom::ConversionResultShape* clone() const;
|
||||
virtual ifcopenshell::geom::conversion_result_shape* clone() const;
|
||||
|
||||
virtual double bounding_box(void*&) const {
|
||||
throw std::runtime_error("Not implemented");
|
||||
@@ -70,36 +70,36 @@ namespace ifcopenshell {
|
||||
virtual int num_faces() const;
|
||||
|
||||
// @todo this must be something with a virtual dtor so that we can delete it.
|
||||
virtual std::pair<OpaqueCoordinate<3>, OpaqueCoordinate<3>> bounding_box() const;
|
||||
virtual std::pair<opaque_coordinate<3>, opaque_coordinate<3>> bounding_box() const;
|
||||
|
||||
virtual OpaqueNumber length();
|
||||
virtual OpaqueNumber area();
|
||||
virtual OpaqueNumber volume();
|
||||
virtual opaque_number length();
|
||||
virtual opaque_number area();
|
||||
virtual opaque_number volume();
|
||||
|
||||
virtual OpaqueCoordinate<3> position();
|
||||
virtual OpaqueCoordinate<3> axis();
|
||||
virtual OpaqueCoordinate<4> plane_equation();
|
||||
virtual opaque_coordinate<3> position();
|
||||
virtual opaque_coordinate<3> axis();
|
||||
virtual opaque_coordinate<4> plane_equation();
|
||||
|
||||
virtual std::vector<ConversionResultShape*> convex_decomposition();
|
||||
virtual ConversionResultShape* halfspaces();
|
||||
virtual ConversionResultShape* solid();
|
||||
virtual ConversionResultShape* box();
|
||||
virtual ConversionResultShape* wrap_in_compound();
|
||||
virtual std::vector<conversion_result_shape*> convex_decomposition();
|
||||
virtual conversion_result_shape* halfspaces();
|
||||
virtual conversion_result_shape* solid();
|
||||
virtual conversion_result_shape* box();
|
||||
virtual conversion_result_shape* wrap_in_compound();
|
||||
|
||||
virtual std::vector<ConversionResultShape*> vertices();
|
||||
virtual std::vector<ConversionResultShape*> edges();
|
||||
virtual std::vector<ConversionResultShape*> facets();
|
||||
virtual std::vector<conversion_result_shape*> vertices();
|
||||
virtual std::vector<conversion_result_shape*> edges();
|
||||
virtual std::vector<conversion_result_shape*> facets();
|
||||
|
||||
virtual ConversionResultShape* add(ConversionResultShape*);
|
||||
virtual ConversionResultShape* subtract(ConversionResultShape*);
|
||||
virtual ConversionResultShape* intersect(ConversionResultShape*);
|
||||
virtual ConversionResultShape* concat(ConversionResultShape*);
|
||||
virtual conversion_result_shape* add(conversion_result_shape*);
|
||||
virtual conversion_result_shape* subtract(conversion_result_shape*);
|
||||
virtual conversion_result_shape* intersect(conversion_result_shape*);
|
||||
virtual conversion_result_shape* concat(conversion_result_shape*);
|
||||
|
||||
virtual std::size_t map(OpaqueCoordinate<4>& from, OpaqueCoordinate<4>& to);
|
||||
virtual std::size_t map(const std::vector<OpaqueCoordinate<4>>& from, const std::vector<OpaqueCoordinate<4>>& to);
|
||||
virtual ConversionResultShape* moved(ifcopenshell::geometry::taxonomy::matrix4::ptr) const;
|
||||
virtual std::size_t map(opaque_coordinate<4>& from, opaque_coordinate<4>& to);
|
||||
virtual std::size_t map(const std::vector<opaque_coordinate<4>>& from, const std::vector<opaque_coordinate<4>>& to);
|
||||
virtual conversion_result_shape* moved(ifcopenshell::geom::taxonomy::matrix4::ptr) const;
|
||||
|
||||
virtual bool surface_area_along_direction(double tol, const ifcopenshell::geometry::taxonomy::matrix4::ptr&, double& along_x, double& along_y, double& along_z) const;
|
||||
virtual bool surface_area_along_direction(double tol, const ifcopenshell::geom::taxonomy::matrix4::ptr&, double& along_x, double& along_y, double& along_z) const;
|
||||
private:
|
||||
TopoDS_Shape shape_;
|
||||
};
|
||||
|
||||
@@ -41,10 +41,10 @@ namespace {
|
||||
};
|
||||
}
|
||||
|
||||
using namespace ifcopenshell::geometry;
|
||||
using namespace ifcopenshell::geom;
|
||||
|
||||
bool IfcGeom::OpenCascadeKernel::convert_openings(const express::Base& entity, const std::vector<std::pair<taxonomy::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
|
||||
const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes) {
|
||||
bool ifcopenshell::geom::open_cascade_kernel::convert_openings(const express::base& entity, const std::vector<std::pair<taxonomy::ptr, ifcopenshell::geom::taxonomy::matrix4>>& openings,
|
||||
const ifcopenshell::geom::conversion_results& entity_shapes, const ifcopenshell::geom::taxonomy::matrix4& entity_trsf, ifcopenshell::geom::conversion_results& cut_shapes) {
|
||||
|
||||
util::boolean_settings bst;
|
||||
bst.attempt_2d = settings_.get<settings::BooleanAttempt2d>().get();
|
||||
@@ -83,13 +83,13 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const express::Base& entity, c
|
||||
Eigen::Matrix4d relative = entity_trsf.ccomponents().inverse() * opening_trsf.ccomponents();
|
||||
// opening_trsf = relative;
|
||||
|
||||
IfcGeom::ConversionResults opening_shapes;
|
||||
ifcopenshell::geom::conversion_results opening_shapes;
|
||||
|
||||
// @todo
|
||||
AbstractKernel::convert(op.first, opening_shapes);
|
||||
abstract_kernel::convert(op.first, opening_shapes);
|
||||
|
||||
for (unsigned int i = 0; i < opening_shapes.size(); ++i) {
|
||||
auto opening_shape_i = std::static_pointer_cast<OpenCascadeShape>(opening_shapes[i].Shape())->shape();
|
||||
auto opening_shape_i = std::static_pointer_cast<open_cascade_shape>(opening_shapes[i].Shape())->shape();
|
||||
const TopoDS_Shape& opening_shape_unlocated = util::ensure_fit_for_subtraction(opening_shape_i, settings_.get<settings::Precision>().get());
|
||||
|
||||
auto gtrsf = opening_shapes[i].Placement();
|
||||
@@ -110,7 +110,7 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const express::Base& entity, c
|
||||
std::sort(opening_vector.begin(), opening_vector.end(), opening_sorter());
|
||||
|
||||
// Iterate over the shapes of the IfcProduct
|
||||
for (IfcGeom::ConversionResults::const_iterator it3 = entity_shapes.begin(); it3 != entity_shapes.end(); ++it3) {
|
||||
for (ifcopenshell::geom::conversion_results::const_iterator it3 = entity_shapes.begin(); it3 != entity_shapes.end(); ++it3) {
|
||||
|
||||
TopoDS_Compound C;
|
||||
BRep_Builder B;
|
||||
@@ -119,7 +119,7 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const express::Base& entity, c
|
||||
|
||||
std::list<TopoDS_Shape> parts;
|
||||
|
||||
auto it3_shape = std::static_pointer_cast<OpenCascadeShape>(it3->Shape())->shape();
|
||||
auto it3_shape = std::static_pointer_cast<open_cascade_shape>(it3->Shape())->shape();
|
||||
if (it3_shape.IsNull()) {
|
||||
logger_.error("GEO", 187, "Null operand");
|
||||
continue;
|
||||
@@ -142,8 +142,8 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const express::Base& entity, c
|
||||
if (!is_manifold) {
|
||||
// force sewing, edge identity might have been mudied by FixAdvFace.FixOrientation.MSG5 to fix interior loop winding order
|
||||
NCollection_List<TopoDS_Shape> list;
|
||||
IfcGeom::util::shape_to_face_list(entity_part, list);
|
||||
IfcGeom::util::create_solid_from_faces(list, entity_part, settings_.get<settings::Precision>().get(), true);
|
||||
ifcopenshell::geom::util::shape_to_face_list(entity_part, list);
|
||||
ifcopenshell::geom::util::create_solid_from_faces(list, entity_part, settings_.get<settings::Precision>().get(), true);
|
||||
is_manifold = util::is_manifold(entity_part);
|
||||
if (is_manifold) {
|
||||
logger_.warning("GEO", 188, "Successfully sewed non-manifold first operand");
|
||||
@@ -160,8 +160,8 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const express::Base& entity, c
|
||||
try {
|
||||
mv.Perform();
|
||||
auto entity_part_2 = mv.Shape();
|
||||
if (IfcGeom::util::count(entity_part_2, TopAbs_FACE) == 0) {
|
||||
failure = "Empty result (no faces) for BOPAlgo_MakerVolume; original was " + std::to_string(IfcGeom::util::count(entity_part, TopAbs_FACE));
|
||||
if (ifcopenshell::geom::util::count(entity_part_2, TopAbs_FACE) == 0) {
|
||||
failure = "Empty result (no faces) for BOPAlgo_MakerVolume; original was " + std::to_string(ifcopenshell::geom::util::count(entity_part, TopAbs_FACE));
|
||||
} else {
|
||||
is_manifold = util::is_manifold(entity_part_2);
|
||||
logger_.warning("GEO", 189, std::string("Sucessfully detected exterior volume to non-manifold first operand; shape is now ") + (is_manifold ? std::string("manifold") : std::string("non-manifold")));
|
||||
@@ -262,24 +262,24 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const express::Base& entity, c
|
||||
combined_result = C;
|
||||
}
|
||||
|
||||
cut_shapes.push_back(IfcGeom::ConversionResult(it3->ItemId(), new OpenCascadeShape(combined_result), it3->StylePtr()));
|
||||
cut_shapes.push_back(ifcopenshell::geom::conversion_result(it3->ItemId(), new open_cascade_shape(combined_result), it3->StylePtr()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::OpenCascadeKernel::unify_shapes(const IfcGeom::ConversionResults& input, IfcGeom::ConversionResults& output) {
|
||||
bool ifcopenshell::geom::open_cascade_kernel::unify_shapes(const ifcopenshell::geom::conversion_results& input, ifcopenshell::geom::conversion_results& output) {
|
||||
std::transform(input.begin(), input.end(), std::back_inserter(output), [this](auto v) {
|
||||
auto& s = std::static_pointer_cast<OpenCascadeShape>(v.Shape())->shape();
|
||||
return IfcGeom::ConversionResult(
|
||||
auto& s = std::static_pointer_cast<open_cascade_shape>(v.Shape())->shape();
|
||||
return ifcopenshell::geom::conversion_result(
|
||||
v.ItemId(),
|
||||
v.Placement(),
|
||||
new OpenCascadeShape(util::unify(s, settings_.get<ifcopenshell::geometry::settings::Precision>().get())),
|
||||
new open_cascade_shape(util::unify(s, settings_.get<ifcopenshell::geom::settings::Precision>().get())),
|
||||
v.StylePtr());
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, IfcGeom::ConversionResults& results) {
|
||||
bool ifcopenshell::geom::open_cascade_kernel::convert_impl(const taxonomy::revolve::ptr r, ifcopenshell::geom::conversion_results& results) {
|
||||
|
||||
|
||||
gp_Ax1 ax(
|
||||
@@ -298,16 +298,16 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
shape = BRepPrimAPI_MakeRevol(face, ax);
|
||||
}
|
||||
|
||||
results.emplace_back(ConversionResult(
|
||||
results.emplace_back(conversion_result(
|
||||
r->instance.id(),
|
||||
r->matrix,
|
||||
new OpenCascadeShape(shape),
|
||||
new open_cascade_shape(shape),
|
||||
r->surface_style
|
||||
));
|
||||
return true;
|
||||
}
|
||||
|
||||
// IfcSchema::IfcRelVoidsElement::list::ptr IfcGeom::Kernel::find_openings(IfcSchema::IfcProduct* product) {
|
||||
// IfcSchema::IfcRelVoidsElement::list::ptr ifcopenshell::geom::Kernel::find_openings(IfcSchema::IfcProduct* product) {
|
||||
// std::vector<IfcSchema::IfcRelVoidsElement*> rs;
|
||||
//
|
||||
// if (product->declaration().is(IfcSchema::IfcElement::Class()) && !product->declaration().is(IfcSchema::IfcOpeningElement::Class())) {
|
||||
@@ -345,7 +345,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
// return openings;
|
||||
// }
|
||||
//
|
||||
// const IfcSchema::IfcMaterial* IfcGeom::Kernel::get_single_material_association(const IfcSchema::IfcProduct* product) {
|
||||
// const IfcSchema::IfcMaterial* ifcopenshell::geom::Kernel::get_single_material_association(const IfcSchema::IfcProduct* product) {
|
||||
// IfcSchema::IfcMaterial* single_material = 0;
|
||||
// IfcSchema::IfcRelAssociatesMaterial::list::ptr associated_materials = product->HasAssociations()->as<IfcSchema::IfcRelAssociatesMaterial>();
|
||||
// if (associated_materials->size() == 1) {
|
||||
@@ -367,15 +367,15 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
// return single_material;
|
||||
// }
|
||||
//
|
||||
// IfcGeom::BRepElement* IfcGeom::Kernel::create_brep_for_representation_and_product(
|
||||
// ifcopenshell::geom::brep_element* ifcopenshell::geom::Kernel::create_brep_for_representation_and_product(
|
||||
// const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product)
|
||||
// {
|
||||
// std::stringstream representation_id_builder;
|
||||
//
|
||||
// representation_id_builder << representation->data().id();
|
||||
//
|
||||
// IfcGeom::Representation::BRep* shape;
|
||||
// IfcGeom::ConversionResults shapes, shapes2;
|
||||
// ifcopenshell::geom::Representation::brep* shape;
|
||||
// ifcopenshell::geom::conversion_results shapes, shapes2;
|
||||
//
|
||||
// if (!convert_shapes(representation, shapes)) {
|
||||
// return 0;
|
||||
@@ -430,7 +430,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
// const IfcSchema::IfcMaterial* single_material = get_single_material_association(product);
|
||||
// if (single_material) {
|
||||
// auto s = get_style(single_material);
|
||||
// for (IfcGeom::ConversionResults::iterator it = shapes.begin(); it != shapes.end(); ++it) {
|
||||
// for (ifcopenshell::geom::conversion_results::iterator it = shapes.begin(); it != shapes.end(); ++it) {
|
||||
// if (!it->hasStyle() && s) {
|
||||
// it->setStyle(s);
|
||||
// material_style_applied = true;
|
||||
@@ -438,7 +438,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
// }
|
||||
// } else {
|
||||
// bool some_items_without_style = false;
|
||||
// for (IfcGeom::ConversionResults::iterator it = shapes.begin(); it != shapes.end(); ++it) {
|
||||
// for (ifcopenshell::geom::conversion_results::iterator it = shapes.begin(); it != shapes.end(); ++it) {
|
||||
// if (!it->hasStyle() && util::count(it->Shape(), TopAbs_FACE)) {
|
||||
// some_items_without_style = true;
|
||||
// break;
|
||||
@@ -458,7 +458,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
// if (s.hasStyle()) {
|
||||
// for (auto& p : style_cache) {
|
||||
// if (p.second == s.StylePtr()) {
|
||||
// std::const_pointer_cast<IfcGeom::SurfaceStyle>(p.second)->Transparency() = settings.force_space_transparency();
|
||||
// std::const_pointer_cast<ifcopenshell::geom::SurfaceStyle>(p.second)->Transparency() = settings.force_space_transparency();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
@@ -467,7 +467,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
//
|
||||
// int parent_id = -1;
|
||||
// try {
|
||||
// express::Entity* parent_object = get_decomposing_entity(product);
|
||||
// express::entity* parent_object = get_decomposing_entity(product);
|
||||
// if (parent_object && parent_object->as<IfcSchema::IfcObjectDefinition>()) {
|
||||
// parent_id = parent_object->data().id();
|
||||
// }
|
||||
@@ -496,13 +496,13 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
// const std::string product_type = product->declaration().name();
|
||||
// ElementSettings element_settings(settings, getValue(GV_LENGTH_UNIT), product_type);
|
||||
//
|
||||
// if (!settings.get(IfcGeom::IteratorSettings::DISABLE_OPENING_SUBTRACTIONS) && openings && openings->size()) {
|
||||
// if (!settings.get(ifcopenshell::geom::IteratorSettings::DISABLE_OPENING_SUBTRACTIONS) && openings && openings->size()) {
|
||||
// representation_id_builder << "-openings";
|
||||
// for (IfcSchema::IfcRelVoidsElement::list::it it = openings->begin(); it != openings->end(); ++it) {
|
||||
// representation_id_builder << "-" << (*it)->data().id();
|
||||
// }
|
||||
//
|
||||
// IfcGeom::ConversionResults opened_shapes;
|
||||
// ifcopenshell::geom::conversion_results opened_shapes;
|
||||
// bool caught_error = false;
|
||||
// try {
|
||||
// convert_openings(product, openings, shapes, trsf, opened_shapes);
|
||||
@@ -518,22 +518,22 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
// }
|
||||
//
|
||||
// if (settings.get(IteratorSettings::USE_WORLD_COORDS)) {
|
||||
// for (IfcGeom::ConversionResults::iterator it = opened_shapes.begin(); it != opened_shapes.end(); ++it) {
|
||||
// for (ifcopenshell::geom::conversion_results::iterator it = opened_shapes.begin(); it != opened_shapes.end(); ++it) {
|
||||
// it->prepend(trsf);
|
||||
// }
|
||||
// trsf = gp_Trsf();
|
||||
// representation_id_builder << "-world-coords";
|
||||
// }
|
||||
// shape = new IfcGeom::Representation::BRep(element_settings, representation_id_builder.str(), opened_shapes);
|
||||
// shape = new ifcopenshell::geom::Representation::brep(element_settings, representation_id_builder.str(), opened_shapes);
|
||||
// } else if (settings.get(IteratorSettings::USE_WORLD_COORDS)) {
|
||||
// for (IfcGeom::ConversionResults::iterator it = shapes.begin(); it != shapes.end(); ++it) {
|
||||
// for (ifcopenshell::geom::conversion_results::iterator it = shapes.begin(); it != shapes.end(); ++it) {
|
||||
// it->prepend(trsf);
|
||||
// }
|
||||
// trsf = gp_Trsf();
|
||||
// representation_id_builder << "-world-coords";
|
||||
// shape = new IfcGeom::Representation::BRep(element_settings, representation_id_builder.str(), shapes);
|
||||
// shape = new ifcopenshell::geom::Representation::brep(element_settings, representation_id_builder.str(), shapes);
|
||||
// } else {
|
||||
// shape = new IfcGeom::Representation::BRep(element_settings, representation_id_builder.str(), shapes);
|
||||
// shape = new ifcopenshell::geom::Representation::brep(element_settings, representation_id_builder.str(), shapes);
|
||||
// }
|
||||
//
|
||||
// std::string context_string = "";
|
||||
@@ -543,7 +543,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
// context_string = *representation->ContextOfItems()->ContextType();
|
||||
// }
|
||||
//
|
||||
// auto elem = new BRepElement(
|
||||
// auto elem = new brep_element(
|
||||
// product->data().id(),
|
||||
// parent_id,
|
||||
// name,
|
||||
@@ -551,7 +551,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
// guid,
|
||||
// context_string,
|
||||
// trsf,
|
||||
// boost::shared_ptr<IfcGeom::Representation::BRep>(shape),
|
||||
// boost::shared_ptr<ifcopenshell::geom::Representation::brep>(shape),
|
||||
// product
|
||||
// );
|
||||
//
|
||||
@@ -627,7 +627,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
// return elem;
|
||||
// }
|
||||
//
|
||||
// IfcSchema::IfcRepresentation* IfcGeom::Kernel::representation_mapped_to(const IfcSchema::IfcRepresentation* representation) {
|
||||
// IfcSchema::IfcRepresentation* ifcopenshell::geom::Kernel::representation_mapped_to(const IfcSchema::IfcRepresentation* representation) {
|
||||
// IfcSchema::IfcRepresentation* representation_mapped_to = 0;
|
||||
// try {
|
||||
// IfcSchema::IfcRepresentationItem::list::ptr items = representation->Items();
|
||||
@@ -652,7 +652,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
// return representation_mapped_to;
|
||||
// }
|
||||
//
|
||||
// IfcSchema::IfcProduct::list::ptr IfcGeom::Kernel::products_represented_by(const IfcSchema::IfcRepresentation* representation) {
|
||||
// IfcSchema::IfcProduct::list::ptr ifcopenshell::geom::Kernel::products_represented_by(const IfcSchema::IfcRepresentation* representation) {
|
||||
// IfcSchema::IfcProduct::list::ptr products(new IfcSchema::IfcProduct::list);
|
||||
//
|
||||
// IfcSchema::IfcProductRepresentation::list::ptr prodreps = representation->OfProductRepresentation();
|
||||
@@ -710,13 +710,13 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
// return products;
|
||||
// }
|
||||
//
|
||||
// IfcGeom::BRepElement* IfcGeom::Kernel::create_brep_for_processed_representation(
|
||||
// ifcopenshell::geom::brep_element* ifcopenshell::geom::Kernel::create_brep_for_processed_representation(
|
||||
// const IteratorSettings& /*settings*/, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product,
|
||||
// IfcGeom::BRepElement* brep)
|
||||
// ifcopenshell::geom::brep_element* brep)
|
||||
// {
|
||||
// int parent_id = -1;
|
||||
// try {
|
||||
// express::Entity* parent_object = get_decomposing_entity(product);
|
||||
// express::entity* parent_object = get_decomposing_entity(product);
|
||||
// if (parent_object && parent_object->as<IfcSchema::IfcObjectDefinition>()) {
|
||||
// parent_id = parent_object->data().id();
|
||||
// }
|
||||
@@ -747,7 +747,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
//
|
||||
// const std::string product_type = product->declaration().name();
|
||||
//
|
||||
// return new BRepElement(
|
||||
// return new brep_element(
|
||||
// product->data().id(),
|
||||
// parent_id,
|
||||
// name,
|
||||
@@ -760,17 +760,17 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// bool IfcGeom::Kernel::convert_layerset(const IfcSchema::IfcProduct* product, std::vector<Handle_Geom_Surface>& surfaces, std::vector<std::shared_ptr<const SurfaceStyle>>& styles, std::vector<double>& thicknesses) {
|
||||
// bool ifcopenshell::geom::Kernel::convert_layerset(const IfcSchema::IfcProduct* product, std::vector<Handle_Geom_Surface>& surfaces, std::vector<std::shared_ptr<const SurfaceStyle>>& styles, std::vector<double>& thicknesses) {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// bool IfcGeom::Kernel::find_wall_end_points(const IfcSchema::IfcWall* wall, gp_Pnt& start, gp_Pnt& end) {
|
||||
// bool ifcopenshell::geom::Kernel::find_wall_end_points(const IfcSchema::IfcWall* wall, gp_Pnt& start, gp_Pnt& end) {
|
||||
// IfcSchema::IfcRepresentation* axis_representation = find_representation(wall, "Axis");
|
||||
// if (!axis_representation) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// ConversionResults items;
|
||||
// conversion_results items;
|
||||
// {
|
||||
// Kernel temp = *this;
|
||||
// temp.setValue(GV_DIMENSIONALITY, -1.);
|
||||
@@ -778,7 +778,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
// }
|
||||
//
|
||||
// TopoDS_Vertex a, b;
|
||||
// for (ConversionResults::const_iterator it = items.begin(); it != items.end(); ++it) {
|
||||
// for (conversion_results::const_iterator it = items.begin(); it != items.end(); ++it) {
|
||||
// TopExp_Explorer exp(it->Shape(), TopAbs_VERTEX);
|
||||
// for (; exp.More(); exp.Next()) {
|
||||
// b = TopoDS::Vertex(exp.Current());
|
||||
@@ -798,7 +798,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// bool IfcGeom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const ConversionResults& items, const std::vector<Handle_Geom_Surface>& surfaces, const std::vector<double>& thicknesses, std::vector< std::vector<Handle_Geom_Surface> >& result) {
|
||||
// bool ifcopenshell::geom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const conversion_results& items, const std::vector<Handle_Geom_Surface>& surfaces, const std::vector<double>& thicknesses, std::vector< std::vector<Handle_Geom_Surface> >& result) {
|
||||
// /*
|
||||
// * @todo isn't it easier to do this based on the non-folded surfaces of
|
||||
// * the connected walls and fold both pairs of layersets simultaneously?
|
||||
@@ -969,7 +969,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// ConversionResults axis_items;
|
||||
// conversion_results axis_items;
|
||||
// {
|
||||
// Kernel temp = *this;
|
||||
// temp.setValue(GV_DIMENSIONALITY, -1.);
|
||||
@@ -1172,7 +1172,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
// return folds_made;
|
||||
// }
|
||||
//
|
||||
// IfcSchema::IfcRepresentation* IfcGeom::Kernel::find_representation(const IfcSchema::IfcProduct* product, const std::string& identifier) {
|
||||
// IfcSchema::IfcRepresentation* ifcopenshell::geom::Kernel::find_representation(const IfcSchema::IfcProduct* product, const std::string& identifier) {
|
||||
// if (!product->Representation()) return 0;
|
||||
// IfcSchema::IfcProductRepresentation* prod_rep = product->Representation();
|
||||
// IfcSchema::IfcRepresentation::list::ptr reps = prod_rep->Representations();
|
||||
@@ -1184,7 +1184,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
// const IfcSchema::IfcRepresentationptr IfcGeom::Kernel::find_item_carrying_style(const IfcSchema::IfcRepresentationptr item) {
|
||||
// const IfcSchema::IfcRepresentationptr ifcopenshell::geom::Kernel::find_item_carrying_style(const IfcSchema::IfcRepresentationptr item) {
|
||||
// if (item->StyledByItem()->size()) {
|
||||
// return item;
|
||||
// }
|
||||
@@ -1206,7 +1206,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
// return item;
|
||||
// }
|
||||
//
|
||||
// bool IfcGeom::Kernel::is_identity_transform(ifcopenshell::IfcBaseInterface* l) {
|
||||
// bool ifcopenshell::geom::Kernel::is_identity_transform(ifcopenshell::IfcBaseInterface* l) {
|
||||
// IfcSchema::IfcAxis2Placement2D* ax2d;
|
||||
// IfcSchema::IfcAxis2Placement3D* ax3d;
|
||||
//
|
||||
@@ -1244,11 +1244,11 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// void IfcGeom::Kernel::set_conversion_placement_rel_to_type(const ifcopenshell::declaration* type) {
|
||||
// void ifcopenshell::geom::Kernel::set_conversion_placement_rel_to_type(const ifcopenshell::declaration* type) {
|
||||
// placement_rel_to_type_ = type;
|
||||
// }
|
||||
//
|
||||
// void IfcGeom::Kernel::set_conversion_placement_rel_to_instance(const express::Entity* instance) {
|
||||
// void ifcopenshell::geom::Kernel::set_conversion_placement_rel_to_instance(const express::entity* instance) {
|
||||
// placement_rel_to_instance_ = instance;
|
||||
// }
|
||||
//
|
||||
@@ -1288,7 +1288,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
//
|
||||
// #define Kernel POSTFIX_SCHEMA(Kernel)
|
||||
//
|
||||
// std::shared_ptr<const IfcGeom::SurfaceStyle> IfcGeom::Kernel::internalize_surface_style(const std::pair<express::Base, express::Base>& shading_styles) {
|
||||
// std::shared_ptr<const ifcopenshell::geom::SurfaceStyle> ifcopenshell::geom::Kernel::internalize_surface_style(const std::pair<express::base, express::base>& shading_styles) {
|
||||
// if (shading_styles.second == 0) {
|
||||
// return 0;
|
||||
// }
|
||||
@@ -1354,11 +1354,11 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
// return style_cache[surface_style_id] = surface_style_ptr_const;
|
||||
// }
|
||||
//
|
||||
// std::shared_ptr<const IfcGeom::SurfaceStyle> IfcGeom::Kernel::get_style(const IfcSchema::IfcRepresentationptr item) {
|
||||
// std::shared_ptr<const ifcopenshell::geom::SurfaceStyle> ifcopenshell::geom::Kernel::get_style(const IfcSchema::IfcRepresentationptr item) {
|
||||
// return internalize_surface_style(get_surface_style<IfcSchema::IfcSurfaceStyleShading>(item));
|
||||
// }
|
||||
//
|
||||
// std::shared_ptr<const IfcGeom::SurfaceStyle> IfcGeom::Kernel::get_style(const IfcSchema::IfcMaterial* material) {
|
||||
// std::shared_ptr<const ifcopenshell::geom::SurfaceStyle> ifcopenshell::geom::Kernel::get_style(const IfcSchema::IfcMaterial* material) {
|
||||
// IfcSchema::IfcMaterialDefinitionRepresentation::list::ptr defs = material->HasRepresentation();
|
||||
// for (IfcSchema::IfcMaterialDefinitionRepresentation::list::it jt = defs->begin(); jt != defs->end(); ++jt) {
|
||||
// IfcSchema::IfcRepresentation::list::ptr reps = (*jt)->Representations();
|
||||
@@ -1373,11 +1373,11 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// auto material_style = std::make_shared<IfcGeom::SurfaceStyle>(material->data().id(), material->Name());
|
||||
// auto material_style = std::make_shared<ifcopenshell::geom::SurfaceStyle>(material->data().id(), material->Name());
|
||||
// return style_cache[material->data().id()] = material_style;
|
||||
// }
|
||||
//
|
||||
// void IfcGeom::Kernel::apply_layerset(IfcGeom::ConversionResults& r, const ifcopenshell::geometry::layerset_information& info) {
|
||||
// void ifcopenshell::geom::Kernel::apply_layerset(ifcopenshell::geom::conversion_results& r, const ifcopenshell::geom::layerset_information& info) {
|
||||
// convert(info.layers);
|
||||
//
|
||||
// if (info.layers.empty()) {
|
||||
@@ -1398,8 +1398,8 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// IfcGeom::ConversionResults r2;
|
||||
// if (IfcGeom::util::apply_layerset(r, const std::vector<ifcopenshell::geometry::taxonomy::style>&, ConversionResults& r2, double tol)) {
|
||||
// ifcopenshell::geom::conversion_results r2;
|
||||
// if (ifcopenshell::geom::util::apply_layerset(r, const std::vector<ifcopenshell::geom::taxonomy::style>&, conversion_results& r2, double tol)) {
|
||||
// std::swap(r, r2)
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -69,9 +69,9 @@ bool handle_occt_exception(Fn&& fn) {
|
||||
}
|
||||
}
|
||||
|
||||
namespace IfcGeom {
|
||||
namespace ifcopenshell::geom {
|
||||
|
||||
class IFC_GEOMLIBRARY_API OpenCascadeKernel : public ifcopenshell::geometry::kernels::AbstractKernel {
|
||||
class IFC_GEOMLIBRARY_API open_cascade_kernel : public ifcopenshell::geom::kernels::abstract_kernel {
|
||||
private:
|
||||
|
||||
/*
|
||||
@@ -84,16 +84,16 @@ private:
|
||||
|
||||
class faceset_helper {
|
||||
private:
|
||||
OpenCascadeKernel* kernel_;
|
||||
open_cascade_kernel* kernel_;
|
||||
std::set<int> duplicates_;
|
||||
std::map<int, int> vertex_mapping_;
|
||||
std::map<std::pair<int, int>, TopoDS_Edge> edges_;
|
||||
double eps_;
|
||||
bool non_manifold_;
|
||||
|
||||
void loop_(const ifcopenshell::geometry::taxonomy::loop::ptr ps, const std::function<void(int, int, bool)>& callback);
|
||||
void loop_(const ifcopenshell::geom::taxonomy::loop::ptr ps, const std::function<void(int, int, bool)>& callback);
|
||||
public:
|
||||
faceset_helper(OpenCascadeKernel* kernel, const ifcopenshell::geometry::taxonomy::shell::ptr l);
|
||||
faceset_helper(open_cascade_kernel* kernel, const ifcopenshell::geom::taxonomy::shell::ptr l);
|
||||
~faceset_helper();
|
||||
|
||||
bool non_manifold() const { return non_manifold_; }
|
||||
@@ -102,54 +102,54 @@ private:
|
||||
|
||||
bool edge(int A, int B, TopoDS_Edge& e);
|
||||
|
||||
bool wire(const ifcopenshell::geometry::taxonomy::loop::ptr loop, TopoDS_Wire& wire);
|
||||
bool wires(const ifcopenshell::geometry::taxonomy::loop::ptr loop, NCollection_List<TopoDS_Shape>& wires);
|
||||
bool wire(const ifcopenshell::geom::taxonomy::loop::ptr loop, TopoDS_Wire& wire);
|
||||
bool wires(const ifcopenshell::geom::taxonomy::loop::ptr loop, NCollection_List<TopoDS_Shape>& wires);
|
||||
};
|
||||
|
||||
faceset_helper* faceset_helper_;
|
||||
|
||||
double precision_;
|
||||
public:
|
||||
OpenCascadeKernel(const ifcopenshell::geometry::Settings& settings, ::logger& logger = ::logger::root())
|
||||
: AbstractKernel("opencascade", settings, logger)
|
||||
open_cascade_kernel(const ifcopenshell::geom::settings& settings, ::logger& logger = ::logger::root())
|
||||
: abstract_kernel("opencascade", settings, logger)
|
||||
, faceset_helper_(nullptr)
|
||||
, precision_(settings.get<ifcopenshell::geometry::settings::Precision>().get())
|
||||
, precision_(settings.get<ifcopenshell::geom::settings::Precision>().get())
|
||||
{}
|
||||
|
||||
virtual AbstractKernel* clone(::logger& logger) const {
|
||||
return new OpenCascadeKernel(settings(), logger);
|
||||
virtual abstract_kernel* clone(::logger& logger) const {
|
||||
return new open_cascade_kernel(settings(), logger);
|
||||
}
|
||||
|
||||
virtual bool supports_boolean_operations() const { return true; }
|
||||
|
||||
bool convert(const ifcopenshell::geometry::taxonomy::extrusion::ptr, TopoDS_Shape&);
|
||||
bool convert(const ifcopenshell::geometry::taxonomy::face::ptr, TopoDS_Shape&, bool reversed_surface = false);
|
||||
bool convert(const ifcopenshell::geometry::taxonomy::loop::ptr, TopoDS_Wire&);
|
||||
bool convert(const ifcopenshell::geometry::taxonomy::matrix4::ptr, gp_GTrsf&);
|
||||
bool convert(const ifcopenshell::geometry::taxonomy::shell::ptr, TopoDS_Shape&);
|
||||
bool convert(const ifcopenshell::geometry::taxonomy::solid::ptr, TopoDS_Shape&);
|
||||
bool convert(const ifcopenshell::geometry::taxonomy::loft::ptr, TopoDS_Shape&);
|
||||
bool convert(const ifcopenshell::geometry::taxonomy::bspline_surface::ptr bs, Handle(Geom_Surface) surf);
|
||||
bool convert(const ifcopenshell::geometry::taxonomy::sweep_along_curve::ptr, TopoDS_Shape&);
|
||||
bool convert(const ifcopenshell::geom::taxonomy::extrusion::ptr, TopoDS_Shape&);
|
||||
bool convert(const ifcopenshell::geom::taxonomy::face::ptr, TopoDS_Shape&, bool reversed_surface = false);
|
||||
bool convert(const ifcopenshell::geom::taxonomy::loop::ptr, TopoDS_Wire&);
|
||||
bool convert(const ifcopenshell::geom::taxonomy::matrix4::ptr, gp_GTrsf&);
|
||||
bool convert(const ifcopenshell::geom::taxonomy::shell::ptr, TopoDS_Shape&);
|
||||
bool convert(const ifcopenshell::geom::taxonomy::solid::ptr, TopoDS_Shape&);
|
||||
bool convert(const ifcopenshell::geom::taxonomy::loft::ptr, TopoDS_Shape&);
|
||||
bool convert(const ifcopenshell::geom::taxonomy::bspline_surface::ptr bs, Handle(Geom_Surface) surf);
|
||||
bool convert(const ifcopenshell::geom::taxonomy::sweep_along_curve::ptr, TopoDS_Shape&);
|
||||
|
||||
virtual bool convert_impl(const ifcopenshell::geometry::taxonomy::edge::ptr, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const ifcopenshell::geometry::taxonomy::loop::ptr, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const ifcopenshell::geometry::taxonomy::face::ptr, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const ifcopenshell::geometry::taxonomy::solid::ptr, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const ifcopenshell::geometry::taxonomy::shell::ptr, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const ifcopenshell::geometry::taxonomy::extrusion::ptr, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const ifcopenshell::geometry::taxonomy::revolve::ptr, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const ifcopenshell::geometry::taxonomy::boolean_result::ptr, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const ifcopenshell::geometry::taxonomy::loft::ptr, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const ifcopenshell::geometry::taxonomy::sweep_along_curve::ptr, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const ifcopenshell::geom::taxonomy::edge::ptr, ifcopenshell::geom::conversion_results&);
|
||||
virtual bool convert_impl(const ifcopenshell::geom::taxonomy::loop::ptr, ifcopenshell::geom::conversion_results&);
|
||||
virtual bool convert_impl(const ifcopenshell::geom::taxonomy::face::ptr, ifcopenshell::geom::conversion_results&);
|
||||
virtual bool convert_impl(const ifcopenshell::geom::taxonomy::solid::ptr, ifcopenshell::geom::conversion_results&);
|
||||
virtual bool convert_impl(const ifcopenshell::geom::taxonomy::shell::ptr, ifcopenshell::geom::conversion_results&);
|
||||
virtual bool convert_impl(const ifcopenshell::geom::taxonomy::extrusion::ptr, ifcopenshell::geom::conversion_results&);
|
||||
virtual bool convert_impl(const ifcopenshell::geom::taxonomy::revolve::ptr, ifcopenshell::geom::conversion_results&);
|
||||
virtual bool convert_impl(const ifcopenshell::geom::taxonomy::boolean_result::ptr, ifcopenshell::geom::conversion_results&);
|
||||
virtual bool convert_impl(const ifcopenshell::geom::taxonomy::loft::ptr, ifcopenshell::geom::conversion_results&);
|
||||
virtual bool convert_impl(const ifcopenshell::geom::taxonomy::sweep_along_curve::ptr, ifcopenshell::geom::conversion_results&);
|
||||
|
||||
virtual bool convert_openings(const express::Base& entity, const std::vector<std::pair<ifcopenshell::geometry::taxonomy::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
|
||||
const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes);
|
||||
virtual bool unify_shapes(const IfcGeom::ConversionResults& input, IfcGeom::ConversionResults& output);
|
||||
virtual bool convert_openings(const express::base& entity, const std::vector<std::pair<ifcopenshell::geom::taxonomy::ptr, ifcopenshell::geom::taxonomy::matrix4>>& openings,
|
||||
const ifcopenshell::geom::conversion_results& entity_shapes, const ifcopenshell::geom::taxonomy::matrix4& entity_trsf, ifcopenshell::geom::conversion_results& cut_shapes);
|
||||
virtual bool unify_shapes(const ifcopenshell::geom::conversion_results& input, ifcopenshell::geom::conversion_results& output);
|
||||
|
||||
typedef std::variant<boost::blank, Handle(Geom_Curve), TopoDS_Wire> curve_creation_visitor_result_type;
|
||||
curve_creation_visitor_result_type convert_curve(const ifcopenshell::geometry::taxonomy::ptr);
|
||||
Handle(Geom_Surface) convert_surface(const ifcopenshell::geometry::taxonomy::ptr);
|
||||
curve_creation_visitor_result_type convert_curve(const ifcopenshell::geom::taxonomy::ptr);
|
||||
Handle(Geom_Surface) convert_surface(const ifcopenshell::geom::taxonomy::ptr);
|
||||
|
||||
template <typename T, typename U>
|
||||
static T convert_xyz(const U& u) {
|
||||
@@ -164,8 +164,8 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
express::Base POSTFIX_SCHEMA(tesselate_)(const TopoDS_Shape& shape, double deflection);
|
||||
express::Base POSTFIX_SCHEMA(serialise_)(const TopoDS_Shape& shape, bool advanced);
|
||||
express::base POSTFIX_SCHEMA(tesselate_)(const TopoDS_Shape& shape, double deflection);
|
||||
express::base POSTFIX_SCHEMA(serialise_)(const TopoDS_Shape& shape, bool advanced);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
|
||||
// For axis placements detect equality early in order for the
|
||||
// relatively computionaly expensive gp_Trsf calculation to be skipped
|
||||
bool IfcGeom::util::axis_equal(const gp_Ax3 & a, const gp_Ax3 & b, double tolerance) {
|
||||
bool ifcopenshell::geom::util::axis_equal(const gp_Ax3 & a, const gp_Ax3 & b, double tolerance) {
|
||||
if (!a.Location().IsEqual(b.Location(), tolerance)) return false;
|
||||
// Note that the tolerance below is angular, above is linear. Since architectural
|
||||
// objects are about 1m'ish in scale, it should be somewhat equivalent. Besides,
|
||||
@@ -67,13 +67,13 @@ bool IfcGeom::util::axis_equal(const gp_Ax3 & a, const gp_Ax3 & b, double tolera
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::util::axis_equal(const gp_Ax2d & a, const gp_Ax2d & b, double tolerance) {
|
||||
bool ifcopenshell::geom::util::axis_equal(const gp_Ax2d & a, const gp_Ax2d & b, double tolerance) {
|
||||
if (!a.Location().IsEqual(b.Location(), tolerance)) return false;
|
||||
if (!a.Direction().IsEqual(b.Direction(), tolerance)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
int IfcGeom::util::count(const TopoDS_Shape& s, TopAbs_ShapeEnum t, bool unique) {
|
||||
int ifcopenshell::geom::util::count(const TopoDS_Shape& s, TopAbs_ShapeEnum t, bool unique) {
|
||||
if (unique) {
|
||||
NCollection_IndexedMap<TopoDS_Shape, TopTools_ShapeMapHasher> map;
|
||||
TopExp::MapShapes(s, t, map);
|
||||
@@ -89,7 +89,7 @@ int IfcGeom::util::count(const TopoDS_Shape& s, TopAbs_ShapeEnum t, bool unique)
|
||||
}
|
||||
|
||||
|
||||
int IfcGeom::util::surface_genus(const TopoDS_Shape& s) {
|
||||
int ifcopenshell::geom::util::surface_genus(const TopoDS_Shape& s) {
|
||||
int nv = count(s, TopAbs_VERTEX, true);
|
||||
int ne = count(s, TopAbs_EDGE, true);
|
||||
int nf = count(s, TopAbs_FACE, true);
|
||||
@@ -100,7 +100,7 @@ int IfcGeom::util::surface_genus(const TopoDS_Shape& s) {
|
||||
return genus;
|
||||
}
|
||||
|
||||
bool IfcGeom::util::is_manifold(const TopoDS_Shape& a) {
|
||||
bool ifcopenshell::geom::util::is_manifold(const TopoDS_Shape& a) {
|
||||
if (a.ShapeType() == TopAbs_COMPOUND || a.ShapeType() == TopAbs_SOLID) {
|
||||
TopoDS_Iterator it(a);
|
||||
for (; it.More(); it.Next()) {
|
||||
@@ -134,7 +134,7 @@ bool IfcGeom::util::is_manifold(const TopoDS_Shape& a) {
|
||||
}
|
||||
|
||||
|
||||
bool IfcGeom::util::is_nested_compound_of_solid(const TopoDS_Shape& s, int depth) {
|
||||
bool ifcopenshell::geom::util::is_nested_compound_of_solid(const TopoDS_Shape& s, int depth) {
|
||||
if (s.ShapeType() == TopAbs_COMPOUND) {
|
||||
TopoDS_Iterator it(s);
|
||||
for (; it.More(); it.Next()) {
|
||||
@@ -174,23 +174,23 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
bool IfcGeom::util::is_identity(const gp_Trsf2d& t, double tolerance) {
|
||||
bool ifcopenshell::geom::util::is_identity(const gp_Trsf2d& t, double tolerance) {
|
||||
return is_identity_helper(t, tolerance);
|
||||
}
|
||||
|
||||
bool IfcGeom::util::is_identity(const gp_GTrsf2d& t, double tolerance) {
|
||||
bool ifcopenshell::geom::util::is_identity(const gp_GTrsf2d& t, double tolerance) {
|
||||
return is_identity_helper(t, tolerance);
|
||||
}
|
||||
|
||||
bool IfcGeom::util::is_identity(const gp_Trsf& t, double tolerance) {
|
||||
bool ifcopenshell::geom::util::is_identity(const gp_Trsf& t, double tolerance) {
|
||||
return is_identity_helper(t, tolerance);
|
||||
}
|
||||
|
||||
bool IfcGeom::util::is_identity(const gp_GTrsf& t, double tolerance) {
|
||||
bool ifcopenshell::geom::util::is_identity(const gp_GTrsf& t, double tolerance) {
|
||||
return is_identity_helper(t, tolerance);
|
||||
}
|
||||
|
||||
gp_Trsf IfcGeom::util::combine_offset_and_rotation(const gp_Vec & offset, const gp_Quaternion & rotation) {
|
||||
gp_Trsf ifcopenshell::geom::util::combine_offset_and_rotation(const gp_Vec & offset, const gp_Quaternion & rotation) {
|
||||
auto offset_transform = gp_Trsf{};
|
||||
offset_transform.SetTranslation(offset);
|
||||
|
||||
@@ -201,7 +201,7 @@ gp_Trsf IfcGeom::util::combine_offset_and_rotation(const gp_Vec & offset, const
|
||||
}
|
||||
|
||||
|
||||
bool IfcGeom::util::project(const opencascade::handle<Geom_Surface>& srf, const TopoDS_Shape& shp, double& u1, double& v1, double& u2, double& v2, double widen) {
|
||||
bool ifcopenshell::geom::util::project(const opencascade::handle<Geom_Surface>& srf, const TopoDS_Shape& shp, double& u1, double& v1, double& u2, double& v2, double widen) {
|
||||
// @todo std::unique_ptr for C++11
|
||||
ShapeAnalysis_Surface* sas = 0;
|
||||
opencascade::handle<Geom_Plane> pln;
|
||||
@@ -281,7 +281,7 @@ bool IfcGeom::util::project(const opencascade::handle<Geom_Surface>& srf, const
|
||||
}
|
||||
|
||||
|
||||
TopoDS_Shape IfcGeom::util::apply_transformation(const TopoDS_Shape& s, const gp_Trsf& t) {
|
||||
TopoDS_Shape ifcopenshell::geom::util::apply_transformation(const TopoDS_Shape& s, const gp_Trsf& t) {
|
||||
if (t.Form() == gp_Identity) {
|
||||
return s;
|
||||
} else {
|
||||
@@ -295,7 +295,7 @@ TopoDS_Shape IfcGeom::util::apply_transformation(const TopoDS_Shape& s, const gp
|
||||
}
|
||||
|
||||
|
||||
TopoDS_Shape IfcGeom::util::apply_transformation(const TopoDS_Shape& s, const gp_GTrsf& t) {
|
||||
TopoDS_Shape ifcopenshell::geom::util::apply_transformation(const TopoDS_Shape& s, const gp_GTrsf& t) {
|
||||
if (t.Form() == gp_Other) {
|
||||
return BRepBuilderAPI_GTransform(s, t, true);
|
||||
} else {
|
||||
@@ -318,7 +318,7 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
TopoDS_Shape IfcGeom::util::apply_transformation(const TopoDS_Shape& s, const ifcopenshell::geometry::taxonomy::matrix4& t) {
|
||||
TopoDS_Shape ifcopenshell::geom::util::apply_transformation(const TopoDS_Shape& s, const ifcopenshell::geom::taxonomy::matrix4& t) {
|
||||
|
||||
gp_GTrsf trsf;
|
||||
if (t.components_) {
|
||||
@@ -353,7 +353,7 @@ TopoDS_Shape IfcGeom::util::apply_transformation(const TopoDS_Shape& s, const if
|
||||
return apply_transformation(s, trsf);
|
||||
}
|
||||
|
||||
bool IfcGeom::util::fit_halfspace(const TopoDS_Shape& a, const TopoDS_Shape& b, TopoDS_Shape& box, double& height, double tol) {
|
||||
bool ifcopenshell::geom::util::fit_halfspace(const TopoDS_Shape& a, const TopoDS_Shape& b, TopoDS_Shape& box, double& height, double tol) {
|
||||
TopExp_Explorer exp(b, TopAbs_FACE);
|
||||
if (!exp.More()) {
|
||||
return false;
|
||||
@@ -451,7 +451,7 @@ bool IfcGeom::util::fit_halfspace(const TopoDS_Shape& a, const TopoDS_Shape& b,
|
||||
}
|
||||
|
||||
|
||||
const opencascade::handle<Geom_Curve> IfcGeom::util::intersect(const opencascade::handle<Geom_Surface>& a, const opencascade::handle<Geom_Surface>& b) {
|
||||
const opencascade::handle<Geom_Curve> ifcopenshell::geom::util::intersect(const opencascade::handle<Geom_Surface>& a, const opencascade::handle<Geom_Surface>& b) {
|
||||
GeomAPI_IntSS x(a, b, 1.e-7);
|
||||
if (x.IsDone() && x.NbLines() == 1) {
|
||||
return x.Line(1);
|
||||
@@ -461,15 +461,15 @@ const opencascade::handle<Geom_Curve> IfcGeom::util::intersect(const opencascade
|
||||
}
|
||||
}
|
||||
|
||||
const opencascade::handle<Geom_Curve> IfcGeom::util::intersect(const opencascade::handle<Geom_Surface>& a, const TopoDS_Face& b) {
|
||||
const opencascade::handle<Geom_Curve> ifcopenshell::geom::util::intersect(const opencascade::handle<Geom_Surface>& a, const TopoDS_Face& b) {
|
||||
return intersect(a, BRep_Tool::Surface(b));
|
||||
}
|
||||
|
||||
const opencascade::handle<Geom_Curve> IfcGeom::util::intersect(const TopoDS_Face& a, const opencascade::handle<Geom_Surface>& b) {
|
||||
const opencascade::handle<Geom_Curve> ifcopenshell::geom::util::intersect(const TopoDS_Face& a, const opencascade::handle<Geom_Surface>& b) {
|
||||
return intersect(BRep_Tool::Surface(a), b);
|
||||
}
|
||||
|
||||
bool IfcGeom::util::intersect(const opencascade::handle<Geom_Curve>& a, const opencascade::handle<Geom_Surface>& b, gp_Pnt& p) {
|
||||
bool ifcopenshell::geom::util::intersect(const opencascade::handle<Geom_Curve>& a, const opencascade::handle<Geom_Surface>& b, gp_Pnt& p) {
|
||||
GeomAPI_IntCS x(a, b);
|
||||
if (x.IsDone() && x.NbPoints() == 1) {
|
||||
p = x.Point(1);
|
||||
@@ -479,11 +479,11 @@ bool IfcGeom::util::intersect(const opencascade::handle<Geom_Curve>& a, const op
|
||||
}
|
||||
}
|
||||
|
||||
bool IfcGeom::util::intersect(const opencascade::handle<Geom_Curve>& a, const TopoDS_Face& b, gp_Pnt &c) {
|
||||
bool ifcopenshell::geom::util::intersect(const opencascade::handle<Geom_Curve>& a, const TopoDS_Face& b, gp_Pnt &c) {
|
||||
return intersect(a, BRep_Tool::Surface(b), c);
|
||||
}
|
||||
|
||||
bool IfcGeom::util::intersect(const opencascade::handle<Geom_Curve>& a, const TopoDS_Shape& b, std::vector<gp_Pnt>& out) {
|
||||
bool ifcopenshell::geom::util::intersect(const opencascade::handle<Geom_Curve>& a, const TopoDS_Shape& b, std::vector<gp_Pnt>& out) {
|
||||
TopExp_Explorer exp(b, TopAbs_FACE);
|
||||
gp_Pnt p;
|
||||
for (; exp.More(); exp.Next()) {
|
||||
@@ -494,7 +494,7 @@ bool IfcGeom::util::intersect(const opencascade::handle<Geom_Curve>& a, const To
|
||||
return !out.empty();
|
||||
}
|
||||
|
||||
bool IfcGeom::util::intersect(const opencascade::handle<Geom_Surface>& a, const TopoDS_Shape& b, std::vector< std::pair<opencascade::handle<Geom_Surface>, opencascade::handle<Geom_Curve> > >& out) {
|
||||
bool ifcopenshell::geom::util::intersect(const opencascade::handle<Geom_Surface>& a, const TopoDS_Shape& b, std::vector< std::pair<opencascade::handle<Geom_Surface>, opencascade::handle<Geom_Curve> > >& out) {
|
||||
TopExp_Explorer exp(b, TopAbs_FACE);
|
||||
for (; exp.More(); exp.Next()) {
|
||||
const TopoDS_Face& f = TopoDS::Face(exp.Current());
|
||||
@@ -507,7 +507,7 @@ bool IfcGeom::util::intersect(const opencascade::handle<Geom_Surface>& a, const
|
||||
return !out.empty();
|
||||
}
|
||||
|
||||
bool IfcGeom::util::closest(const gp_Pnt& a, const std::vector<gp_Pnt>& b, gp_Pnt& c) {
|
||||
bool ifcopenshell::geom::util::closest(const gp_Pnt& a, const std::vector<gp_Pnt>& b, gp_Pnt& c) {
|
||||
double minimal_distance = std::numeric_limits<double>::infinity();
|
||||
for (std::vector<gp_Pnt>::const_iterator it = b.begin(); it != b.end(); ++it) {
|
||||
const double d = a.Distance(*it);
|
||||
@@ -519,26 +519,26 @@ bool IfcGeom::util::closest(const gp_Pnt& a, const std::vector<gp_Pnt>& b, gp_Pn
|
||||
return minimal_distance != std::numeric_limits<double>::infinity();
|
||||
}
|
||||
|
||||
bool IfcGeom::util::project(const opencascade::handle<Geom_Curve>& crv, const gp_Pnt& pt, gp_Pnt& p, double& u, double& d) {
|
||||
bool ifcopenshell::geom::util::project(const opencascade::handle<Geom_Curve>& crv, const gp_Pnt& pt, gp_Pnt& p, double& u, double& d) {
|
||||
ShapeAnalysis_Curve sac;
|
||||
sac.Project(crv, pt, 1e-3, p, u, false);
|
||||
d = pt.Distance(p);
|
||||
return true;
|
||||
}
|
||||
|
||||
double IfcGeom::util::shape_volume(const TopoDS_Shape& s) {
|
||||
double ifcopenshell::geom::util::shape_volume(const TopoDS_Shape& s) {
|
||||
GProp_GProps prop;
|
||||
BRepGProp::VolumeProperties(s, prop);
|
||||
return prop.Mass();
|
||||
}
|
||||
|
||||
double IfcGeom::util::face_area(const TopoDS_Face& f) {
|
||||
double ifcopenshell::geom::util::face_area(const TopoDS_Face& f) {
|
||||
GProp_GProps prop;
|
||||
BRepGProp::SurfaceProperties(f, prop);
|
||||
return prop.Mass();
|
||||
}
|
||||
|
||||
bool IfcGeom::util::is_convex(const TopoDS_Wire& wire, double tol) {
|
||||
bool ifcopenshell::geom::util::is_convex(const TopoDS_Wire& wire, double tol) {
|
||||
for (TopExp_Explorer exp1(wire, TopAbs_VERTEX); exp1.More(); exp1.Next()) {
|
||||
TopoDS_Vertex V1 = TopoDS::Vertex(exp1.Current());
|
||||
gp_Pnt P1 = BRep_Tool::Pnt(V1);
|
||||
@@ -585,12 +585,12 @@ bool IfcGeom::util::is_convex(const TopoDS_Wire& wire, double tol) {
|
||||
return true;
|
||||
}
|
||||
|
||||
TopoDS_Shape IfcGeom::util::halfspace_from_plane(const gp_Pln& pln, const gp_Pnt& cent) {
|
||||
TopoDS_Shape ifcopenshell::geom::util::halfspace_from_plane(const gp_Pln& pln, const gp_Pnt& cent) {
|
||||
TopoDS_Face face = BRepBuilderAPI_MakeFace(pln).Face();
|
||||
return BRepPrimAPI_MakeHalfSpace(face, cent).Solid();
|
||||
}
|
||||
|
||||
gp_Pln IfcGeom::util::plane_from_face(const TopoDS_Face& face) {
|
||||
gp_Pln ifcopenshell::geom::util::plane_from_face(const TopoDS_Face& face) {
|
||||
BRepGProp_Face prop(face);
|
||||
double u1, u2, v1, v2;
|
||||
prop.Bounds(u1, u2, v1, v2);
|
||||
@@ -602,7 +602,7 @@ gp_Pln IfcGeom::util::plane_from_face(const TopoDS_Face& face) {
|
||||
return gp_Pln(p, n);
|
||||
}
|
||||
|
||||
gp_Pnt IfcGeom::util::point_above_plane(const gp_Pln& pln, bool agree) {
|
||||
gp_Pnt ifcopenshell::geom::util::point_above_plane(const gp_Pln& pln, bool agree) {
|
||||
if (agree) {
|
||||
return pln.Location().Translated(pln.Axis().Direction());
|
||||
} else {
|
||||
@@ -610,7 +610,7 @@ gp_Pnt IfcGeom::util::point_above_plane(const gp_Pln& pln, bool agree) {
|
||||
}
|
||||
}
|
||||
|
||||
bool IfcGeom::util::is_compound_of_faces(const TopoDS_Shape& shape) {
|
||||
bool ifcopenshell::geom::util::is_compound_of_faces(const TopoDS_Shape& shape) {
|
||||
bool has_solids = TopExp_Explorer(shape, TopAbs_SOLID).More() != 0;
|
||||
bool has_shells = TopExp_Explorer(shape, TopAbs_SHELL).More() != 0;
|
||||
bool has_compounds = TopExp_Explorer(shape, TopAbs_COMPOUND).More() != 0;
|
||||
@@ -618,7 +618,7 @@ bool IfcGeom::util::is_compound_of_faces(const TopoDS_Shape& shape) {
|
||||
return has_compounds && has_faces && !has_solids && !has_shells;
|
||||
}
|
||||
|
||||
bool IfcGeom::util::shape_to_face_list(const TopoDS_Shape& s, NCollection_List<TopoDS_Shape>& li) {
|
||||
bool ifcopenshell::geom::util::shape_to_face_list(const TopoDS_Shape& s, NCollection_List<TopoDS_Shape>& li) {
|
||||
TopExp_Explorer exp(s, TopAbs_FACE);
|
||||
for (; exp.More(); exp.Next()) {
|
||||
TopoDS_Face face = TopoDS::Face(exp.Current());
|
||||
@@ -627,7 +627,7 @@ bool IfcGeom::util::shape_to_face_list(const TopoDS_Shape& s, NCollection_List<T
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::util::create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& shape, double tol) {
|
||||
bool ifcopenshell::geom::util::create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& shape, double tol) {
|
||||
NCollection_List<TopoDS_Shape> face_list;
|
||||
shape_to_face_list(compound, face_list);
|
||||
if (face_list.Extent() == 0) {
|
||||
@@ -636,7 +636,7 @@ bool IfcGeom::util::create_solid_from_compound(const TopoDS_Shape& compound, Top
|
||||
return create_solid_from_faces(face_list, shape, tol);
|
||||
}
|
||||
|
||||
bool IfcGeom::util::create_solid_from_faces(const NCollection_List<TopoDS_Shape>& face_list, TopoDS_Shape& shape, double tol, bool force_sewing) {
|
||||
bool ifcopenshell::geom::util::create_solid_from_faces(const NCollection_List<TopoDS_Shape>& face_list, TopoDS_Shape& shape, double tol, bool force_sewing) {
|
||||
bool valid_shell = false;
|
||||
|
||||
if (face_list.Extent() == 1) {
|
||||
@@ -803,16 +803,16 @@ bool IfcGeom::util::create_solid_from_faces(const NCollection_List<TopoDS_Shape>
|
||||
return valid_shell;
|
||||
}
|
||||
|
||||
bool IfcGeom::util::flatten_shape_list(const IfcGeom::ConversionResults& shapes, TopoDS_Shape& result, bool fuse, bool create_shell, double tol) {
|
||||
bool ifcopenshell::geom::util::flatten_shape_list(const ifcopenshell::geom::conversion_results& shapes, TopoDS_Shape& result, bool fuse, bool create_shell, double tol) {
|
||||
TopoDS_Compound compound;
|
||||
BRep_Builder builder;
|
||||
builder.MakeCompound(compound);
|
||||
|
||||
result = TopoDS_Shape();
|
||||
|
||||
for (IfcGeom::ConversionResults::const_iterator it = shapes.begin(); it != shapes.end(); ++it) {
|
||||
for (ifcopenshell::geom::conversion_results::const_iterator it = shapes.begin(); it != shapes.end(); ++it) {
|
||||
TopoDS_Shape merged;
|
||||
const TopoDS_Shape& s = std::static_pointer_cast<ifcopenshell::geometry::OpenCascadeShape>(it->Shape())->shape();
|
||||
const TopoDS_Shape& s = std::static_pointer_cast<ifcopenshell::geom::open_cascade_shape>(it->Shape())->shape();
|
||||
if (fuse || create_shell) {
|
||||
merged = util::ensure_fit_for_subtraction(s, tol);
|
||||
} else {
|
||||
@@ -866,7 +866,7 @@ bool IfcGeom::util::flatten_shape_list(const IfcGeom::ConversionResults& shapes,
|
||||
return success;
|
||||
}
|
||||
|
||||
bool IfcGeom::util::validate_shape(const TopoDS_Shape& s) {
|
||||
bool ifcopenshell::geom::util::validate_shape(const TopoDS_Shape& s) {
|
||||
BRepCheck_Analyzer ana(s);
|
||||
if (ana.IsValid()) {
|
||||
return true;
|
||||
@@ -906,7 +906,7 @@ bool IfcGeom::util::validate_shape(const TopoDS_Shape& s) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TopoDS_Shape IfcGeom::util::unify(const TopoDS_Shape& s, double tolerance) {
|
||||
TopoDS_Shape ifcopenshell::geom::util::unify(const TopoDS_Shape& s, double tolerance) {
|
||||
tolerance = (std::min)(min_edge_length(s) / 2., tolerance);
|
||||
ShapeUpgrade_UnifySameDomain usd(s);
|
||||
#if OCC_VERSION_HEX >= 0x70200
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace IfcGeom {
|
||||
namespace ifcopenshell::geom {
|
||||
namespace util {
|
||||
|
||||
IFC_GEOMLIBRARY_API int count(const TopoDS_Shape&, TopAbs_ShapeEnum, bool unique = false);
|
||||
@@ -74,11 +74,11 @@ namespace IfcGeom {
|
||||
IFC_GEOMLIBRARY_API double shape_volume(const TopoDS_Shape& s);
|
||||
IFC_GEOMLIBRARY_API double face_area(const TopoDS_Face& f);
|
||||
|
||||
IFC_GEOMLIBRARY_API TopoDS_Shape apply_transformation(const TopoDS_Shape&, const ifcopenshell::geometry::taxonomy::matrix4& t);
|
||||
IFC_GEOMLIBRARY_API TopoDS_Shape apply_transformation(const TopoDS_Shape&, const ifcopenshell::geom::taxonomy::matrix4& t);
|
||||
IFC_GEOMLIBRARY_API TopoDS_Shape apply_transformation(const TopoDS_Shape&, const gp_Trsf&);
|
||||
IFC_GEOMLIBRARY_API TopoDS_Shape apply_transformation(const TopoDS_Shape&, const gp_GTrsf&);
|
||||
|
||||
IFC_GEOMLIBRARY_API bool flatten_shape_list(const IfcGeom::ConversionResults& shapes, TopoDS_Shape& result, bool fuse, bool create_shell, double tol);
|
||||
IFC_GEOMLIBRARY_API bool flatten_shape_list(const ifcopenshell::geom::conversion_results& shapes, TopoDS_Shape& result, bool fuse, bool create_shell, double tol);
|
||||
IFC_GEOMLIBRARY_API bool validate_shape(const TopoDS_Shape&);
|
||||
|
||||
IFC_GEOMLIBRARY_API TopoDS_Shape unify(const TopoDS_Shape& s, double tolerance);
|
||||
|
||||
@@ -3,9 +3,8 @@
|
||||
#include "boolean_utils.h"
|
||||
#include "base_utils.h"
|
||||
|
||||
using namespace IfcGeom;
|
||||
using namespace ifcopenshell::geometry;
|
||||
using namespace ifcopenshell::geometry::kernels;
|
||||
using namespace ifcopenshell::geom;
|
||||
using namespace ifcopenshell::geom::kernels;
|
||||
|
||||
// @todo should we reapply the technique to apply openings in batches?
|
||||
namespace {
|
||||
@@ -15,7 +14,7 @@ namespace {
|
||||
}
|
||||
};
|
||||
|
||||
bool apply_in_batches(IfcGeom::util::boolean_settings bst, const TopoDS_Shape& first_operand, std::vector< std::pair<double, TopoDS_Shape> >& opening_vector, BOPAlgo_Operation occ_op, TopoDS_Shape& result) {
|
||||
bool apply_in_batches(ifcopenshell::geom::util::boolean_settings bst, const TopoDS_Shape& first_operand, std::vector< std::pair<double, TopoDS_Shape> >& opening_vector, BOPAlgo_Operation occ_op, TopoDS_Shape& result) {
|
||||
auto it = opening_vector.begin();
|
||||
auto jt = it;
|
||||
|
||||
@@ -29,7 +28,7 @@ namespace {
|
||||
}
|
||||
|
||||
TopoDS_Shape intermediate_result;
|
||||
if (IfcGeom::util::boolean_operation(bst, result, opening_list, occ_op, intermediate_result)) {
|
||||
if (ifcopenshell::geom::util::boolean_operation(bst, result, opening_list, occ_op, intermediate_result)) {
|
||||
result = intermediate_result;
|
||||
} else {
|
||||
return false;
|
||||
@@ -83,7 +82,7 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result::ptr br, ConversionResults& results) {
|
||||
bool open_cascade_kernel::convert_impl(const taxonomy::boolean_result::ptr br, conversion_results& results) {
|
||||
return handle_occt_exception([&]() -> bool {
|
||||
bool valid_result = false;
|
||||
bool first = true;
|
||||
@@ -95,11 +94,11 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result::ptr br, Con
|
||||
taxonomy::style::ptr first_item_style;
|
||||
|
||||
for (auto& c : br->children) {
|
||||
IfcGeom::ConversionResults cr;
|
||||
AbstractKernel::convert(c, cr);
|
||||
ifcopenshell::geom::conversion_results cr;
|
||||
abstract_kernel::convert(c, cr);
|
||||
if (first && br->operation == taxonomy::boolean_result::SUBTRACTION) {
|
||||
// @todo A will be null on union/intersection, intended?
|
||||
IfcGeom::util::flatten_shape_list(cr, a, false, true, settings_.get<settings::Precision>().get());
|
||||
ifcopenshell::geom::util::flatten_shape_list(cr, a, false, true, settings_.get<settings::Precision>().get());
|
||||
first_item_style = c->surface_style;
|
||||
if (!first_item_style && c->kind() == taxonomy::COLLECTION) {
|
||||
// @todo recursively right?
|
||||
@@ -107,10 +106,10 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result::ptr br, Con
|
||||
}
|
||||
|
||||
if (settings_.get<settings::DisableBooleanResult>().get()) {
|
||||
results.emplace_back(IfcGeom::ConversionResult(
|
||||
results.emplace_back(ifcopenshell::geom::conversion_result(
|
||||
br->instance.id(),
|
||||
br->matrix,
|
||||
new OpenCascadeShape(a),
|
||||
new open_cascade_shape(a),
|
||||
br->surface_style ? br->surface_style : first_item_style
|
||||
));
|
||||
return true;
|
||||
@@ -123,7 +122,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result::ptr br, Con
|
||||
} else {
|
||||
|
||||
for (auto& r : cr) {
|
||||
auto S = std::static_pointer_cast<OpenCascadeShape>(r.Shape())->shape();
|
||||
auto S = std::static_pointer_cast<open_cascade_shape>(r.Shape())->shape();
|
||||
if (S.IsNull()) {
|
||||
logger_.error("GEO", 120, "Null operand");
|
||||
continue;
|
||||
@@ -190,10 +189,10 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result::ptr br, Con
|
||||
std::swap(r, a);
|
||||
}
|
||||
|
||||
results.emplace_back(IfcGeom::ConversionResult(
|
||||
results.emplace_back(ifcopenshell::geom::conversion_result(
|
||||
br->instance.id(),
|
||||
br->matrix,
|
||||
new OpenCascadeShape(a),
|
||||
new open_cascade_shape(a),
|
||||
br->surface_style ? br->surface_style : first_item_style
|
||||
));
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
|
||||
void IfcGeom::util::copy_operand(const NCollection_List<TopoDS_Shape>& l, NCollection_List<TopoDS_Shape>& r) {
|
||||
void ifcopenshell::geom::util::copy_operand(const NCollection_List<TopoDS_Shape>& l, NCollection_List<TopoDS_Shape>& r) {
|
||||
#if OCC_VERSION_HEX < 0x70000
|
||||
r.Clear();
|
||||
TopTools_ListIteratorOfListOfShape it(l);
|
||||
@@ -45,7 +45,7 @@ void IfcGeom::util::copy_operand(const NCollection_List<TopoDS_Shape>& l, NColle
|
||||
#endif
|
||||
}
|
||||
|
||||
TopoDS_Shape IfcGeom::util::copy_operand(const TopoDS_Shape & s) {
|
||||
TopoDS_Shape ifcopenshell::geom::util::copy_operand(const TopoDS_Shape & s) {
|
||||
#if OCC_VERSION_HEX < 0x70000
|
||||
return BRepBuilderAPI_Copy(s);
|
||||
#else
|
||||
@@ -53,7 +53,7 @@ TopoDS_Shape IfcGeom::util::copy_operand(const TopoDS_Shape & s) {
|
||||
#endif
|
||||
}
|
||||
|
||||
double IfcGeom::util::min_edge_length(const TopoDS_Shape & a) {
|
||||
double ifcopenshell::geom::util::min_edge_length(const TopoDS_Shape & a) {
|
||||
double min_edge_len = std::numeric_limits<double>::infinity();
|
||||
TopExp_Explorer exp(a, TopAbs_EDGE);
|
||||
for (; exp.More(); exp.Next()) {
|
||||
@@ -77,7 +77,7 @@ double IfcGeom::util::min_edge_length(const TopoDS_Shape & a) {
|
||||
return min_edge_len;
|
||||
}
|
||||
|
||||
double IfcGeom::util::min_vertex_edge_distance(const TopoDS_Shape & a, double min_search, double max_search) {
|
||||
double ifcopenshell::geom::util::min_vertex_edge_distance(const TopoDS_Shape & a, double min_search, double max_search) {
|
||||
double M = std::numeric_limits<double>::infinity();
|
||||
|
||||
NCollection_IndexedMap<TopoDS_Shape, TopTools_ShapeMapHasher> vertices, edges;
|
||||
@@ -85,7 +85,7 @@ double IfcGeom::util::min_vertex_edge_distance(const TopoDS_Shape & a, double mi
|
||||
TopExp::MapShapes(a, TopAbs_VERTEX, vertices);
|
||||
TopExp::MapShapes(a, TopAbs_EDGE, edges);
|
||||
|
||||
IfcGeom::impl::tree<int> tree;
|
||||
ifcopenshell::geom::impl::tree<int> tree;
|
||||
|
||||
// Add edges to tree
|
||||
for (int i = 1; i <= edges.Extent(); ++i) {
|
||||
@@ -129,7 +129,7 @@ double IfcGeom::util::min_vertex_edge_distance(const TopoDS_Shape & a, double mi
|
||||
return M;
|
||||
}
|
||||
|
||||
bool IfcGeom::util::faces_overlap(const TopoDS_Face & f, const TopoDS_Face & g) {
|
||||
bool ifcopenshell::geom::util::faces_overlap(const TopoDS_Face & f, const TopoDS_Face & g) {
|
||||
points_on_planar_face_generator pgen(f);
|
||||
|
||||
BRep_Builder B;
|
||||
@@ -141,7 +141,7 @@ bool IfcGeom::util::faces_overlap(const TopoDS_Face & f, const TopoDS_Face & g)
|
||||
|
||||
while (pgen(test)) {
|
||||
TopoDS_Vertex V;
|
||||
B.MakeVertex(V, test, Precision::Confusion());
|
||||
B.MakeVertex(V, test, ::Precision::Confusion());
|
||||
x.LoadS2(V);
|
||||
x.Perform();
|
||||
if (x.IsDone() && x.NbSolution() == 1) {
|
||||
@@ -154,7 +154,7 @@ bool IfcGeom::util::faces_overlap(const TopoDS_Face & f, const TopoDS_Face & g)
|
||||
return true;
|
||||
}
|
||||
|
||||
double IfcGeom::util::min_face_face_distance(const TopoDS_Shape & a, double max_search) {
|
||||
double ifcopenshell::geom::util::min_face_face_distance(const TopoDS_Shape & a, double max_search) {
|
||||
/*
|
||||
NB: This is currently only implemented for planar surfaces.
|
||||
*/
|
||||
@@ -164,7 +164,7 @@ double IfcGeom::util::min_face_face_distance(const TopoDS_Shape & a, double max_
|
||||
|
||||
TopExp::MapShapes(a, TopAbs_FACE, faces);
|
||||
|
||||
IfcGeom::impl::tree<int> tree;
|
||||
ifcopenshell::geom::impl::tree<int> tree;
|
||||
|
||||
// Add faces to tree
|
||||
for (int i = 1; i <= faces.Extent(); ++i) {
|
||||
@@ -229,7 +229,7 @@ double IfcGeom::util::min_face_face_distance(const TopoDS_Shape & a, double max_
|
||||
return M;
|
||||
}
|
||||
|
||||
int IfcGeom::util::bounding_box_overlap(double p, const TopoDS_Shape & a, const NCollection_List<TopoDS_Shape> & b, NCollection_List<TopoDS_Shape> & c) {
|
||||
int ifcopenshell::geom::util::bounding_box_overlap(double p, const TopoDS_Shape & a, const NCollection_List<TopoDS_Shape> & b, NCollection_List<TopoDS_Shape> & c) {
|
||||
int N = 0;
|
||||
|
||||
Bnd_Box A;
|
||||
@@ -258,7 +258,7 @@ int IfcGeom::util::bounding_box_overlap(double p, const TopoDS_Shape & a, const
|
||||
return N;
|
||||
}
|
||||
|
||||
bool IfcGeom::util::get_edge_axis(const TopoDS_Edge & e, gp_Ax1 & ax) {
|
||||
bool ifcopenshell::geom::util::get_edge_axis(const TopoDS_Edge & e, gp_Ax1 & ax) {
|
||||
double _, __;
|
||||
|
||||
auto crv = BRep_Tool::Curve(e, _, __);
|
||||
@@ -279,7 +279,7 @@ bool IfcGeom::util::get_edge_axis(const TopoDS_Edge & e, gp_Ax1 & ax) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IfcGeom::util::is_subset(const NCollection_IndexedMap<TopoDS_Shape, TopTools_ShapeMapHasher>& lhs, const NCollection_IndexedMap<TopoDS_Shape, TopTools_ShapeMapHasher>& rhs) {
|
||||
bool ifcopenshell::geom::util::is_subset(const NCollection_IndexedMap<TopoDS_Shape, TopTools_ShapeMapHasher>& lhs, const NCollection_IndexedMap<TopoDS_Shape, TopTools_ShapeMapHasher>& rhs) {
|
||||
if (rhs.Extent() < lhs.Extent()) {
|
||||
return false;
|
||||
}
|
||||
@@ -292,7 +292,7 @@ bool IfcGeom::util::is_subset(const NCollection_IndexedMap<TopoDS_Shape, TopTool
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::util::is_extrusion(const gp_Vec & v, const TopoDS_Shape & s, TopoDS_Face & base, std::pair<double, double>& interval) {
|
||||
bool ifcopenshell::geom::util::is_extrusion(const gp_Vec & v, const TopoDS_Shape & s, TopoDS_Face & base, std::pair<double, double>& interval) {
|
||||
// This assumes UnifySameDomain has been processed on s, so that
|
||||
// the extrusion top and bottom are a single face.
|
||||
|
||||
@@ -405,7 +405,7 @@ bool IfcGeom::util::is_extrusion(const gp_Vec & v, const TopoDS_Shape & s, TopoD
|
||||
return true;
|
||||
}
|
||||
|
||||
int IfcGeom::util::eliminate_narrow_operands(double prec, const NCollection_List<TopoDS_Shape>& bs, NCollection_List<TopoDS_Shape> & c, ::logger& logger) {
|
||||
int ifcopenshell::geom::util::eliminate_narrow_operands(double prec, const NCollection_List<TopoDS_Shape>& bs, NCollection_List<TopoDS_Shape> & c, ::logger& logger) {
|
||||
int N = 0;
|
||||
NCollection_List<TopoDS_Shape>::Iterator it(bs);
|
||||
for (; it.More(); it.Next()) {
|
||||
@@ -429,7 +429,7 @@ int IfcGeom::util::eliminate_narrow_operands(double prec, const NCollection_List
|
||||
return N;
|
||||
}
|
||||
|
||||
int IfcGeom::util::eliminate_touching_operands(double prec, const TopoDS_Shape & a, const NCollection_List<TopoDS_Shape> & bs, NCollection_List<TopoDS_Shape> & c) {
|
||||
int ifcopenshell::geom::util::eliminate_touching_operands(double prec, const TopoDS_Shape & a, const NCollection_List<TopoDS_Shape> & bs, NCollection_List<TopoDS_Shape> & c) {
|
||||
NCollection_IndexedMap<TopoDS_Shape, TopTools_ShapeMapHasher> a_faces;
|
||||
TopExp::MapShapes(a, TopAbs_FACE, a_faces);
|
||||
|
||||
@@ -445,7 +445,7 @@ int IfcGeom::util::eliminate_touching_operands(double prec, const TopoDS_Shape &
|
||||
NCollection_IndexedMap<TopoDS_Shape, TopTools_ShapeMapHasher> a_vertices;
|
||||
TopExp::MapShapes(a, TopAbs_VERTEX, a_vertices);
|
||||
|
||||
IfcGeom::impl::tree<int> tree;
|
||||
ifcopenshell::geom::impl::tree<int> tree;
|
||||
|
||||
// Add faces to tree
|
||||
for (int i = 1; i <= a_faces.Extent(); ++i) {
|
||||
@@ -573,8 +573,8 @@ int IfcGeom::util::eliminate_touching_operands(double prec, const TopoDS_Shape &
|
||||
return N;
|
||||
}
|
||||
|
||||
bool IfcGeom::util::boolean_subtraction_2d_using_builder(const TopoDS_Shape & a_input, const NCollection_List<TopoDS_Shape> & b_input, TopoDS_Shape & result, double eps, ::logger& logger) {
|
||||
IfcGeom::impl::tree<int> edge_tree;
|
||||
bool ifcopenshell::geom::util::boolean_subtraction_2d_using_builder(const TopoDS_Shape & a_input, const NCollection_List<TopoDS_Shape> & b_input, TopoDS_Shape & result, double eps, ::logger& logger) {
|
||||
ifcopenshell::geom::impl::tree<int> edge_tree;
|
||||
|
||||
NCollection_List<TopoDS_Shape> ab_input = b_input;
|
||||
ab_input.Prepend(a_input);
|
||||
@@ -756,7 +756,7 @@ bool IfcGeom::util::boolean_subtraction_2d_using_builder(const TopoDS_Shape & a_
|
||||
|
||||
// Now build a tree to find inner wires contained in other inner wires
|
||||
// NB first wire is *not* in this tree
|
||||
IfcGeom::impl::tree<int> wire_tree;
|
||||
ifcopenshell::geom::impl::tree<int> wire_tree;
|
||||
for (size_t wire_index = 1; wire_index < wires.size(); ++wire_index) {
|
||||
wire_tree.add(wire_index, wires[wire_index]);
|
||||
}
|
||||
@@ -806,11 +806,11 @@ bool IfcGeom::util::boolean_subtraction_2d_using_builder(const TopoDS_Shape & a_
|
||||
return true;
|
||||
}
|
||||
|
||||
void IfcGeom::util::points_on_planar_face_generator::reset() {
|
||||
void ifcopenshell::geom::util::points_on_planar_face_generator::reset() {
|
||||
i = j = (int)inset_;
|
||||
}
|
||||
|
||||
bool IfcGeom::util::points_on_planar_face_generator::operator()(gp_Pnt& p) {
|
||||
bool ifcopenshell::geom::util::points_on_planar_face_generator::operator()(gp_Pnt& p) {
|
||||
while (j < N) {
|
||||
double u = u0 + (u1 - u0) * i / N;
|
||||
double v = v0 + (v1 - v0) * j / N;
|
||||
@@ -832,7 +832,7 @@ bool IfcGeom::util::points_on_planar_face_generator::operator()(gp_Pnt& p) {
|
||||
}
|
||||
|
||||
|
||||
bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const TopoDS_Shape& a_input, const NCollection_List<TopoDS_Shape>& b_input, BOPAlgo_Operation op, TopoDS_Shape& result, double fuzziness) {
|
||||
bool ifcopenshell::geom::util::boolean_operation(const boolean_settings& settings, const TopoDS_Shape& a_input, const NCollection_List<TopoDS_Shape>& b_input, BOPAlgo_Operation op, TopoDS_Shape& result, double fuzziness) {
|
||||
using namespace std::string_literals;
|
||||
|
||||
const bool do_unify = true;
|
||||
@@ -1239,7 +1239,7 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To
|
||||
TopExp::MapShapes(bb, TopAbs_EDGE, edges);
|
||||
TopExp::MapShapesAndAncestors(bb, TopAbs_EDGE, TopAbs_FACE, map);
|
||||
}
|
||||
IfcGeom::impl::tree<int> tree;
|
||||
ifcopenshell::geom::impl::tree<int> tree;
|
||||
for (int i = 1; i <= edges.Extent(); ++i) {
|
||||
tree.add(i, edges.FindKey(i));
|
||||
}
|
||||
@@ -1425,13 +1425,13 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To
|
||||
return success && !result.IsNull();
|
||||
}
|
||||
|
||||
bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const TopoDS_Shape& a, const TopoDS_Shape& b, BOPAlgo_Operation op, TopoDS_Shape& result, double fuzziness) {
|
||||
bool ifcopenshell::geom::util::boolean_operation(const boolean_settings& settings, const TopoDS_Shape& a, const TopoDS_Shape& b, BOPAlgo_Operation op, TopoDS_Shape& result, double fuzziness) {
|
||||
NCollection_List<TopoDS_Shape> bs;
|
||||
bs.Append(b);
|
||||
return boolean_operation(settings, a, bs, op, result, fuzziness);
|
||||
}
|
||||
|
||||
TopoDS_Shape IfcGeom::util::ensure_fit_for_subtraction(const TopoDS_Shape& shape, double tol) {
|
||||
TopoDS_Shape ifcopenshell::geom::util::ensure_fit_for_subtraction(const TopoDS_Shape& shape, double tol) {
|
||||
const bool is_comp = is_compound_of_faces(shape);
|
||||
if (!is_comp) {
|
||||
return shape;
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#include "../../../ifcparse/logger.h"
|
||||
#include "../ifc_geomlibrary_api.h"
|
||||
|
||||
namespace IfcGeom {
|
||||
namespace ifcopenshell::geom {
|
||||
namespace util {
|
||||
|
||||
IFC_GEOMLIBRARY_API void copy_operand(const NCollection_List<TopoDS_Shape>& l, NCollection_List<TopoDS_Shape>& r);
|
||||
@@ -97,7 +97,7 @@ namespace IfcGeom {
|
||||
bool debug, attempt_2d;
|
||||
double precision;
|
||||
// Set by callers that carry a per-conversion logger (e.g. kernels deriving
|
||||
// from AbstractKernel). Falls back to the global ::logger::root() singleton.
|
||||
// from abstract_kernel). Falls back to the global ::logger::root() singleton.
|
||||
::logger* logger = nullptr;
|
||||
::logger& log() const { return logger ? *logger : ::logger::root(); }
|
||||
};
|
||||
|
||||
@@ -2,11 +2,10 @@
|
||||
|
||||
#include <Geom_BSplineSurface.hxx>
|
||||
|
||||
using namespace ifcopenshell::geometry;
|
||||
using namespace ifcopenshell::geometry::kernels;
|
||||
using namespace IfcGeom;
|
||||
using namespace ifcopenshell::geom;
|
||||
using namespace ifcopenshell::geom::kernels;
|
||||
|
||||
bool OpenCascadeKernel::convert(const taxonomy::bspline_surface::ptr bs, Handle(Geom_Surface) surf) {
|
||||
bool open_cascade_kernel::convert(const taxonomy::bspline_surface::ptr bs, Handle(Geom_Surface) surf) {
|
||||
const bool is_rational = !!bs->weights;
|
||||
|
||||
NCollection_Array2<gp_Pnt> Poles(0, (int)bs->control_points.size() - 1, 0, (int)(*bs->control_points.begin()).size() - 1);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#define GU_CULLING_EPSILON_RAY_TRIANGLE FLT_EPSILON*FLT_EPSILON
|
||||
#define PX_MAX_F32 3.4028234663852885981170418348452e+38F
|
||||
|
||||
typedef uint32_t PxU32;
|
||||
typedef uint32_t px_u32;
|
||||
|
||||
// Why can't I use std::clamp?
|
||||
template<typename TC>
|
||||
@@ -357,23 +357,23 @@ double distanceTriangleTriangleSquared(gp_Vec& cp, gp_Vec& cq, const std::array<
|
||||
//Based on the paper A Fast Triangle-Triangle Intersection Test by T. Moeller
|
||||
//http://web.stanford.edu/class/cs277/resources/papers/Moller1997b.pdf
|
||||
namespace {
|
||||
struct Interval
|
||||
struct interval
|
||||
{
|
||||
double min;
|
||||
double max;
|
||||
gp_Vec minPoint;
|
||||
gp_Vec maxPoint;
|
||||
|
||||
Interval() : min(FLT_MAX), max(-FLT_MAX), minPoint(gp_Vec(NAN, NAN, NAN)), maxPoint(gp_Vec(NAN, NAN, NAN)) { }
|
||||
interval() : min(FLT_MAX), max(-FLT_MAX), minPoint(gp_Vec(NAN, NAN, NAN)), maxPoint(gp_Vec(NAN, NAN, NAN)) { }
|
||||
|
||||
static bool overlapOrTouch(const Interval& a, const Interval& b)
|
||||
static bool overlapOrTouch(const interval& a, const interval& b)
|
||||
{
|
||||
return !(a.min > b.max || b.min > a.max);
|
||||
}
|
||||
|
||||
static Interval intersection(const Interval& a, const Interval& b)
|
||||
static interval intersection(const interval& a, const interval& b)
|
||||
{
|
||||
Interval result;
|
||||
interval result;
|
||||
if (!overlapOrTouch(a, b))
|
||||
return result;
|
||||
|
||||
@@ -407,9 +407,9 @@ namespace {
|
||||
// https://github.com/NVIDIA-Omniverse/PhysX/blob/main/LICENSE.md
|
||||
// https://github.com/NVIDIA-Omniverse/PhysX/blob/main/physx/source/geomutils/src/intersection/GuIntersectionTriangleTriangle.cpp
|
||||
// With minor modifications to use gp_Vec type.
|
||||
static Interval computeInterval(double distanceA, double distanceB, double distanceC, const gp_Vec& a, const gp_Vec& b, const gp_Vec& c, const gp_Vec& dir)
|
||||
static interval computeInterval(double distanceA, double distanceB, double distanceC, const gp_Vec& a, const gp_Vec& b, const gp_Vec& c, const gp_Vec& dir)
|
||||
{
|
||||
Interval i;
|
||||
interval i;
|
||||
|
||||
const bool bA = distanceA > 0;
|
||||
const bool bB = distanceB > 0;
|
||||
@@ -441,7 +441,7 @@ static Interval computeInterval(double distanceA, double distanceB, double dista
|
||||
// https://github.com/NVIDIA-Omniverse/PhysX/blob/main/LICENSE.md
|
||||
// https://github.com/NVIDIA-Omniverse/PhysX/blob/main/physx/source/geomutils/src/intersection/GuIntersectionTriangleTriangle.cpp
|
||||
// With minor modifications to use gp_Vec type.
|
||||
double orient2d(const gp_Vec& a, const gp_Vec& b, const gp_Vec& c, PxU32 x, PxU32 y)
|
||||
double orient2d(const gp_Vec& a, const gp_Vec& b, const gp_Vec& c, px_u32 x, px_u32 y)
|
||||
{
|
||||
return (a.Coord(y) - c.Coord(y)) * (b.Coord(x) - c.Coord(x)) - (a.Coord(x) - c.Coord(x)) * (b.Coord(y) - c.Coord(y));
|
||||
}
|
||||
@@ -450,7 +450,7 @@ double orient2d(const gp_Vec& a, const gp_Vec& b, const gp_Vec& c, PxU32 x, PxU3
|
||||
// https://github.com/NVIDIA-Omniverse/PhysX/blob/main/LICENSE.md
|
||||
// https://github.com/NVIDIA-Omniverse/PhysX/blob/main/physx/source/geomutils/src/intersection/GuIntersectionTriangleTriangle.cpp
|
||||
// With minor modifications to use gp_Vec type.
|
||||
double pointInTriangle(const gp_Vec& a, const gp_Vec& b, const gp_Vec& c, const gp_Vec& point, PxU32 x, PxU32 y)
|
||||
double pointInTriangle(const gp_Vec& a, const gp_Vec& b, const gp_Vec& c, const gp_Vec& point, px_u32 x, px_u32 y)
|
||||
{
|
||||
const double ab = orient2d(a, b, point, x, y);
|
||||
const double bc = orient2d(b, c, point, x, y);
|
||||
@@ -466,7 +466,7 @@ double pointInTriangle(const gp_Vec& a, const gp_Vec& b, const gp_Vec& c, const
|
||||
// https://github.com/NVIDIA-Omniverse/PhysX/blob/main/LICENSE.md
|
||||
// https://github.com/NVIDIA-Omniverse/PhysX/blob/main/physx/source/geomutils/src/intersection/GuIntersectionTriangleTriangle.cpp
|
||||
// With minor modifications to use gp_Vec type.
|
||||
double linesIntersect(const gp_Vec& startA, const gp_Vec& endA, const gp_Vec& startB, const gp_Vec& endB, PxU32 x, PxU32 y)
|
||||
double linesIntersect(const gp_Vec& startA, const gp_Vec& endA, const gp_Vec& startB, const gp_Vec& endB, px_u32 x, px_u32 y)
|
||||
{
|
||||
const double aaS = orient2d(startA, endA, startB, x, y);
|
||||
const double aaE = orient2d(startA, endA, endB, x, y);
|
||||
@@ -487,7 +487,7 @@ double linesIntersect(const gp_Vec& startA, const gp_Vec& endA, const gp_Vec& st
|
||||
// https://github.com/NVIDIA-Omniverse/PhysX/blob/main/LICENSE.md
|
||||
// https://github.com/NVIDIA-Omniverse/PhysX/blob/main/physx/source/geomutils/src/intersection/GuIntersectionTriangleTriangle.cpp
|
||||
// With minor modifications to use gp_Vec type.
|
||||
void getProjectionIndices(gp_Vec normal, PxU32& x, PxU32& y)
|
||||
void getProjectionIndices(gp_Vec normal, px_u32& x, px_u32& y)
|
||||
{
|
||||
normal.SetCoord(std::abs(normal.X()), std::abs(normal.Y()), std::abs(normal.Z()));
|
||||
|
||||
@@ -517,8 +517,8 @@ void getProjectionIndices(gp_Vec normal, PxU32& x, PxU32& y)
|
||||
// With minor modifications to use gp_Vec type.
|
||||
bool trianglesIntersectCoplanar(const gp_Vec& p1_n, const gp_Vec& a1, const gp_Vec& b1, const gp_Vec& c1, const gp_Vec& a2, const gp_Vec& b2, const gp_Vec& c2)
|
||||
{
|
||||
PxU32 x = 0;
|
||||
PxU32 y = 0;
|
||||
px_u32 x = 0;
|
||||
px_u32 y = 0;
|
||||
getProjectionIndices(p1_n, x, y);
|
||||
|
||||
const double third = (1.0 / 3.0);
|
||||
@@ -570,18 +570,18 @@ bool trianglesIntersect(const gp_Vec& a1, const gp_Vec& b1, const gp_Vec& c1, co
|
||||
const double l2 = intersectionDirection.SquareMagnitude();
|
||||
intersectionDirection *= 1.0f / std::sqrt(l2);
|
||||
|
||||
const Interval i1 = computeInterval(p2ToA, p2ToB, p2ToC, a1, b1, c1, intersectionDirection);
|
||||
const Interval i2 = computeInterval(p1ToA, p1ToB, p1ToC, a2, b2, c2, intersectionDirection);
|
||||
const interval i1 = computeInterval(p2ToA, p2ToB, p2ToC, a1, b1, c1, intersectionDirection);
|
||||
const interval i2 = computeInterval(p1ToA, p1ToB, p1ToC, a2, b2, c2, intersectionDirection);
|
||||
|
||||
if (Interval::overlapOrTouch(i1, i2))
|
||||
if (interval::overlapOrTouch(i1, i2))
|
||||
{
|
||||
/*if (intersection)
|
||||
{
|
||||
const Interval i = Interval::intersection(i1, i2);
|
||||
const interval i = interval::intersection(i1, i2);
|
||||
intersection->p0 = i.minPoint;
|
||||
intersection->p1 = i.maxPoint;
|
||||
}*/
|
||||
const Interval i = Interval::intersection(i1, i2);
|
||||
const interval i = interval::intersection(i1, i2);
|
||||
int1 = i.minPoint;
|
||||
int2 = i.maxPoint;
|
||||
return true;
|
||||
|
||||
@@ -2,11 +2,10 @@
|
||||
|
||||
#include <BRepPrimAPI_MakePrism.hxx>
|
||||
|
||||
using namespace ifcopenshell::geometry;
|
||||
using namespace ifcopenshell::geometry::kernels;
|
||||
using namespace IfcGeom;
|
||||
using namespace ifcopenshell::geom;
|
||||
using namespace ifcopenshell::geom::kernels;
|
||||
|
||||
bool OpenCascadeKernel::convert(const taxonomy::extrusion::ptr extrusion, TopoDS_Shape& shape) {
|
||||
bool open_cascade_kernel::convert(const taxonomy::extrusion::ptr extrusion, TopoDS_Shape& shape) {
|
||||
const double& height = extrusion->depth;
|
||||
|
||||
if (height < settings_.get<settings::Precision>().get()) {
|
||||
@@ -71,7 +70,7 @@ bool OpenCascadeKernel::convert(const taxonomy::extrusion::ptr extrusion, TopoDS
|
||||
return !shape.IsNull();
|
||||
}
|
||||
|
||||
bool OpenCascadeKernel::convert_impl(const taxonomy::extrusion::ptr extrusion, IfcGeom::ConversionResults& results) {
|
||||
bool open_cascade_kernel::convert_impl(const taxonomy::extrusion::ptr extrusion, ifcopenshell::geom::conversion_results& results) {
|
||||
return handle_occt_exception([&]() -> bool {
|
||||
|
||||
TopoDS_Shape shape;
|
||||
@@ -79,10 +78,10 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::extrusion::ptr extrusion, I
|
||||
return false;
|
||||
}
|
||||
|
||||
results.emplace_back(ConversionResult(
|
||||
results.emplace_back(conversion_result(
|
||||
extrusion->instance.id(),
|
||||
extrusion->matrix,
|
||||
new OpenCascadeShape(shape),
|
||||
new open_cascade_shape(shape),
|
||||
extrusion->surface_style
|
||||
));
|
||||
return true;
|
||||
|
||||
@@ -63,15 +63,14 @@
|
||||
#include "wire_utils.h"
|
||||
#include "base_utils.h"
|
||||
|
||||
using namespace ifcopenshell::geometry;
|
||||
using namespace ifcopenshell::geometry::kernels;
|
||||
using namespace IfcGeom;
|
||||
using namespace IfcGeom::util;
|
||||
using namespace ifcopenshell::geom;
|
||||
using namespace ifcopenshell::geom::kernels;
|
||||
using namespace ifcopenshell::geom::util;
|
||||
|
||||
|
||||
namespace {
|
||||
struct surface_creation_visitor {
|
||||
OpenCascadeKernel* kernel;
|
||||
open_cascade_kernel* kernel;
|
||||
Handle(Geom_Surface) result;
|
||||
|
||||
Handle(Geom_Surface) operator()(const taxonomy::bspline_surface::ptr& bs) {
|
||||
@@ -122,34 +121,34 @@ namespace {
|
||||
Handle(Geom_Surface) operator()(const taxonomy::plane::ptr& p) {
|
||||
const auto& m = p->matrix->ccomponents();
|
||||
return result = Handle(Geom_Surface)(new Geom_Plane(
|
||||
OpenCascadeKernel::convert_xyz2<gp_Pnt>(m.col(3)),
|
||||
OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(2))));
|
||||
open_cascade_kernel::convert_xyz2<gp_Pnt>(m.col(3)),
|
||||
open_cascade_kernel::convert_xyz2<gp_Dir>(m.col(2))));
|
||||
}
|
||||
|
||||
Handle(Geom_Surface) operator()(const taxonomy::cylinder::ptr& c) {
|
||||
const auto& m = c->matrix->ccomponents();
|
||||
return result = Handle(Geom_Surface)(new Geom_CylindricalSurface(gp_Ax3(
|
||||
OpenCascadeKernel::convert_xyz2<gp_Pnt>(m.col(3)),
|
||||
OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(2)),
|
||||
OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(0))
|
||||
open_cascade_kernel::convert_xyz2<gp_Pnt>(m.col(3)),
|
||||
open_cascade_kernel::convert_xyz2<gp_Dir>(m.col(2)),
|
||||
open_cascade_kernel::convert_xyz2<gp_Dir>(m.col(0))
|
||||
), c->radius));
|
||||
}
|
||||
|
||||
Handle(Geom_Surface) operator()(const taxonomy::sphere::ptr& s) {
|
||||
const auto& m = s->matrix->ccomponents();
|
||||
return result = Handle(Geom_Surface)(new Geom_SphericalSurface(gp_Ax3(
|
||||
OpenCascadeKernel::convert_xyz2<gp_Pnt>(m.col(3)),
|
||||
OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(2)),
|
||||
OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(0))
|
||||
open_cascade_kernel::convert_xyz2<gp_Pnt>(m.col(3)),
|
||||
open_cascade_kernel::convert_xyz2<gp_Dir>(m.col(2)),
|
||||
open_cascade_kernel::convert_xyz2<gp_Dir>(m.col(0))
|
||||
), s->radius));
|
||||
}
|
||||
|
||||
Handle(Geom_Surface) operator()(const taxonomy::torus::ptr& t) {
|
||||
const auto& m = t->matrix->ccomponents();
|
||||
return result = Handle(Geom_Surface)(new Geom_ToroidalSurface(gp_Ax3(
|
||||
OpenCascadeKernel::convert_xyz2<gp_Pnt>(m.col(3)),
|
||||
OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(2)),
|
||||
OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(0))
|
||||
open_cascade_kernel::convert_xyz2<gp_Pnt>(m.col(3)),
|
||||
open_cascade_kernel::convert_xyz2<gp_Dir>(m.col(2)),
|
||||
open_cascade_kernel::convert_xyz2<gp_Dir>(m.col(0))
|
||||
), t->radius1, t->radius2));
|
||||
}
|
||||
|
||||
@@ -204,7 +203,7 @@ namespace {
|
||||
|
||||
result = Handle(Geom_Surface)(new Geom_SurfaceOfLinearExtrusion(
|
||||
crv,
|
||||
OpenCascadeKernel::convert_xyz<gp_Dir>(*e->direction)
|
||||
open_cascade_kernel::convert_xyz<gp_Dir>(*e->direction)
|
||||
));
|
||||
|
||||
result->Transform(tr);
|
||||
@@ -214,8 +213,8 @@ namespace {
|
||||
|
||||
Handle(Geom_Surface) operator()(const taxonomy::revolve::ptr& e) {
|
||||
gp_Ax1 ax(
|
||||
OpenCascadeKernel::convert_xyz<gp_Pnt>(*e->axis_origin),
|
||||
OpenCascadeKernel::convert_xyz<gp_Dir>(*e->direction));
|
||||
open_cascade_kernel::convert_xyz<gp_Pnt>(*e->axis_origin),
|
||||
open_cascade_kernel::convert_xyz<gp_Dir>(*e->direction));
|
||||
|
||||
gp_Trsf tr;
|
||||
if (e->matrix && !e->matrix->is_identity()) {
|
||||
@@ -257,7 +256,7 @@ namespace {
|
||||
};
|
||||
}
|
||||
|
||||
Handle(Geom_Surface) OpenCascadeKernel::convert_surface(const taxonomy::ptr surface) {
|
||||
Handle(Geom_Surface) open_cascade_kernel::convert_surface(const taxonomy::ptr surface) {
|
||||
surface_creation_visitor v{ this };
|
||||
if (dispatch_surface_creation<surface_creation_visitor, 0>::dispatch(surface, v)) {
|
||||
return v.result;
|
||||
@@ -266,7 +265,7 @@ Handle(Geom_Surface) OpenCascadeKernel::convert_surface(const taxonomy::ptr surf
|
||||
}
|
||||
}
|
||||
|
||||
bool OpenCascadeKernel::convert(const taxonomy::face::ptr face, TopoDS_Shape& result, bool reversed_surface) {
|
||||
bool open_cascade_kernel::convert(const taxonomy::face::ptr face, TopoDS_Shape& result, bool reversed_surface) {
|
||||
#ifdef IFOPSH_DEBUG
|
||||
std::ostringstream oss;
|
||||
face->print(oss);
|
||||
@@ -625,16 +624,16 @@ bool OpenCascadeKernel::convert(const taxonomy::face::ptr face, TopoDS_Shape& re
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenCascadeKernel::convert_impl(const taxonomy::face::ptr face, IfcGeom::ConversionResults& results) {
|
||||
bool open_cascade_kernel::convert_impl(const taxonomy::face::ptr face, ifcopenshell::geom::conversion_results& results) {
|
||||
return handle_occt_exception([&]() -> bool {
|
||||
|
||||
TopoDS_Shape shape;
|
||||
if (!convert(face, shape)) {
|
||||
return false;
|
||||
}
|
||||
results.emplace_back(ConversionResult(
|
||||
results.emplace_back(conversion_result(
|
||||
face->instance.id(),
|
||||
new OpenCascadeShape(shape),
|
||||
new open_cascade_shape(shape),
|
||||
face->surface_style
|
||||
));
|
||||
return true;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <TopoDS_Iterator.hxx>
|
||||
|
||||
/* Returns whether wire conforms to a polyhedron, i.e. only edges with linear curves*/
|
||||
bool IfcGeom::util::is_polyhedron(const TopoDS_Wire & wire) {
|
||||
bool ifcopenshell::geom::util::is_polyhedron(const TopoDS_Wire & wire) {
|
||||
double a, b;
|
||||
TopLoc_Location l;
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace IfcGeom {
|
||||
namespace ifcopenshell::geom {
|
||||
namespace util {
|
||||
|
||||
/* Returns whether wire conforms to a polyhedron, i.e. only edges with linear curves*/
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "wire_utils.h"
|
||||
|
||||
namespace {
|
||||
void find_neighbours(IfcGeom::impl::tree<int>& tree, std::vector<std::unique_ptr<gp_Pnt>>& pnts, std::set<int>& visited, int p, double eps) {
|
||||
void find_neighbours(ifcopenshell::geom::impl::tree<int>& tree, std::vector<std::unique_ptr<gp_Pnt>>& pnts, std::set<int>& visited, int p, double eps) {
|
||||
visited.insert(p);
|
||||
|
||||
Bnd_Box b;
|
||||
@@ -25,16 +25,16 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper(
|
||||
OpenCascadeKernel* kernel,
|
||||
const ifcopenshell::geometry::taxonomy::shell::ptr shell
|
||||
ifcopenshell::geom::open_cascade_kernel::faceset_helper::faceset_helper(
|
||||
open_cascade_kernel* kernel,
|
||||
const ifcopenshell::geom::taxonomy::shell::ptr shell
|
||||
)
|
||||
: kernel_(kernel)
|
||||
, non_manifold_(false)
|
||||
{
|
||||
// @todo use pointers?
|
||||
std::vector<ifcopenshell::geometry::taxonomy::point3::ptr> points;
|
||||
std::vector<ifcopenshell::geometry::taxonomy::loop::ptr> loops;
|
||||
std::vector<ifcopenshell::geom::taxonomy::point3::ptr> points;
|
||||
std::vector<ifcopenshell::geom::taxonomy::loop::ptr> loops;
|
||||
std::set<uint32_t> point_identities_visited;
|
||||
|
||||
for (auto& f : shell->children) {
|
||||
@@ -43,7 +43,7 @@ IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper(
|
||||
for (auto& e : l->children) {
|
||||
for (size_t i = 0; i < 2; ++i) {
|
||||
// @todo make sure only cartesian points are provided here
|
||||
auto& p = std::get<ifcopenshell::geometry::taxonomy::point3::ptr>(i == 0 ? e->start : e->end);
|
||||
auto& p = std::get<ifcopenshell::geom::taxonomy::point3::ptr>(i == 0 ? e->start : e->end);
|
||||
if (point_identities_visited.find(p->identity()) == point_identities_visited.end()) {
|
||||
point_identities_visited.insert(p->identity());
|
||||
points.push_back(p);
|
||||
@@ -56,7 +56,7 @@ IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper(
|
||||
std::vector<std::unique_ptr<gp_Pnt>> pnts(points.size());
|
||||
std::vector<TopoDS_Vertex> vertices(pnts.size());
|
||||
|
||||
IfcGeom::impl::tree<int> tree;
|
||||
ifcopenshell::geom::impl::tree<int> tree;
|
||||
|
||||
BRep_Builder B;
|
||||
|
||||
@@ -64,7 +64,7 @@ IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper(
|
||||
for (size_t i = 0; i < points.size(); ++i) {
|
||||
gp_Pnt* p = new gp_Pnt(convert_xyz<gp_Pnt>(*points[i]));
|
||||
pnts[i].reset(p);
|
||||
B.MakeVertex(vertices[i], *p, Precision::Confusion());
|
||||
B.MakeVertex(vertices[i], *p, ::Precision::Confusion());
|
||||
tree.add(i, vertices[i]);
|
||||
box.Add(*p);
|
||||
}
|
||||
@@ -86,12 +86,12 @@ IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper(
|
||||
double bdiff = std::numeric_limits<double>::infinity();
|
||||
for (size_t i = 0; i < 3; ++i) {
|
||||
const double d = bmax[i] - bmin[i];
|
||||
if (d > kernel->settings().get<ifcopenshell::geometry::settings::Precision>().get() * 10. && d < bdiff) {
|
||||
if (d > kernel->settings().get<ifcopenshell::geom::settings::Precision>().get() * 10. && d < bdiff) {
|
||||
bdiff = d;
|
||||
}
|
||||
}
|
||||
|
||||
eps_ = kernel->settings().get<ifcopenshell::geometry::settings::Precision>().get() * 10. * (std::min)(1.0, bdiff);
|
||||
eps_ = kernel->settings().get<ifcopenshell::geom::settings::Precision>().get() * 10. * (std::min)(1.0, bdiff);
|
||||
|
||||
size_t loops_removed, non_manifold, duplicate_faces;
|
||||
|
||||
@@ -111,10 +111,10 @@ IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper(
|
||||
|
||||
edge_use.clear();
|
||||
|
||||
if (eps_ < Precision::Confusion()) {
|
||||
if (eps_ < ::Precision::Confusion()) {
|
||||
// occt uses some hard coded precision values, don't go smaller than that.
|
||||
// @todo, can be reset though with BRepLib::Precision(double)
|
||||
eps_ = Precision::Confusion();
|
||||
eps_ = ::Precision::Confusion();
|
||||
}
|
||||
|
||||
std::vector<bool> retained(pnts.size());
|
||||
@@ -210,14 +210,14 @@ IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper(
|
||||
}
|
||||
}
|
||||
|
||||
void IfcGeom::OpenCascadeKernel::faceset_helper::loop_(const ifcopenshell::geometry::taxonomy::loop::ptr ps, const std::function<void(int, int, bool)>& callback) {
|
||||
void ifcopenshell::geom::open_cascade_kernel::faceset_helper::loop_(const ifcopenshell::geom::taxonomy::loop::ptr ps, const std::function<void(int, int, bool)>& callback) {
|
||||
if (ps->children.size() < 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& edge : ps->children) {
|
||||
auto A = std::get<ifcopenshell::geometry::taxonomy::point3::ptr>(edge->start)->identity();
|
||||
auto B = std::get<ifcopenshell::geometry::taxonomy::point3::ptr>(edge->end)->identity();
|
||||
auto A = std::get<ifcopenshell::geom::taxonomy::point3::ptr>(edge->start)->identity();
|
||||
auto B = std::get<ifcopenshell::geom::taxonomy::point3::ptr>(edge->end)->identity();
|
||||
auto C = vertex_mapping_[A], D = vertex_mapping_[B];
|
||||
bool fwd = C < D;
|
||||
if (!fwd) {
|
||||
@@ -232,7 +232,7 @@ void IfcGeom::OpenCascadeKernel::faceset_helper::loop_(const ifcopenshell::geome
|
||||
}
|
||||
}
|
||||
|
||||
bool IfcGeom::OpenCascadeKernel::faceset_helper::edge(int A, int B, TopoDS_Edge& e) {
|
||||
bool ifcopenshell::geom::open_cascade_kernel::faceset_helper::edge(int A, int B, TopoDS_Edge& e) {
|
||||
auto it = edges_.find({ A, B });
|
||||
if (it == edges_.end()) {
|
||||
return false;
|
||||
@@ -241,7 +241,7 @@ bool IfcGeom::OpenCascadeKernel::faceset_helper::edge(int A, int B, TopoDS_Edge&
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::OpenCascadeKernel::faceset_helper::wire(const ifcopenshell::geometry::taxonomy::loop::ptr loop, TopoDS_Wire& w) {
|
||||
bool ifcopenshell::geom::open_cascade_kernel::faceset_helper::wire(const ifcopenshell::geom::taxonomy::loop::ptr loop, TopoDS_Wire& w) {
|
||||
NCollection_List<TopoDS_Shape> ws;
|
||||
if (!wires(loop, ws)) {
|
||||
return false;
|
||||
@@ -250,7 +250,7 @@ bool IfcGeom::OpenCascadeKernel::faceset_helper::wire(const ifcopenshell::geomet
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::OpenCascadeKernel::faceset_helper::wires(const ifcopenshell::geometry::taxonomy::loop::ptr loop, NCollection_List<TopoDS_Shape>& wires) {
|
||||
bool ifcopenshell::geom::open_cascade_kernel::faceset_helper::wires(const ifcopenshell::geom::taxonomy::loop::ptr loop, NCollection_List<TopoDS_Shape>& wires) {
|
||||
if (duplicates_.find(loop->identity()) != duplicates_.end()) {
|
||||
return false;
|
||||
}
|
||||
@@ -272,10 +272,10 @@ bool IfcGeom::OpenCascadeKernel::faceset_helper::wires(const ifcopenshell::geome
|
||||
wire.Closed(true);
|
||||
|
||||
NCollection_List<TopoDS_Shape> results;
|
||||
if (!kernel_->settings().get<ifcopenshell::geometry::settings::NoWireIntersectionCheck>().get() && util::wire_intersections(wire, results, {
|
||||
!kernel_->settings().get<ifcopenshell::geometry::settings::NoWireIntersectionCheck>().get(),
|
||||
!kernel_->settings().get<ifcopenshell::geometry::settings::NoWireIntersectionTolerance>().get(), 0.,
|
||||
kernel_->settings().get<ifcopenshell::geometry::settings::Precision>().get()}))
|
||||
if (!kernel_->settings().get<ifcopenshell::geom::settings::NoWireIntersectionCheck>().get() && util::wire_intersections(wire, results, {
|
||||
!kernel_->settings().get<ifcopenshell::geom::settings::NoWireIntersectionCheck>().get(),
|
||||
!kernel_->settings().get<ifcopenshell::geom::settings::NoWireIntersectionTolerance>().get(), 0.,
|
||||
kernel_->settings().get<ifcopenshell::geom::settings::Precision>().get()}))
|
||||
{
|
||||
::logger::root().warning("GEO", 170, "Self-intersections with " + boost::lexical_cast<std::string>(results.Extent()) + " cycles detected");
|
||||
non_manifold_ = true;
|
||||
@@ -290,7 +290,7 @@ bool IfcGeom::OpenCascadeKernel::faceset_helper::wires(const ifcopenshell::geome
|
||||
}
|
||||
}
|
||||
|
||||
IfcGeom::OpenCascadeKernel::faceset_helper::~faceset_helper() {
|
||||
ifcopenshell::geom::open_cascade_kernel::faceset_helper::~faceset_helper() {
|
||||
// @todo this is super ugly, but how else can we be notified that the unique_ptr goes out of scope?
|
||||
// Perhaps just supply a custom std::deleter?
|
||||
kernel_->faceset_helper_ = nullptr;
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include <ShapeFix_Shape.hxx>
|
||||
#include <NCollection_IncAllocator.hxx>
|
||||
|
||||
using namespace ifcopenshell::geometry;
|
||||
using namespace ifcopenshell::geom;
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -152,8 +152,8 @@ namespace {
|
||||
surf = BRep_Tool::Surface(TopoDS::Face(s));
|
||||
}
|
||||
|
||||
if ((s.ShapeType() == TopAbs_FACE && IfcGeom::util::split_solid_by_surface(i, surf, a, b)) ||
|
||||
(s.ShapeType() == TopAbs_SHELL && IfcGeom::util::split_solid_by_shell(i, s, a, b))) {
|
||||
if ((s.ShapeType() == TopAbs_FACE && ifcopenshell::geom::util::split_solid_by_surface(i, surf, a, b)) ||
|
||||
(s.ShapeType() == TopAbs_SHELL && ifcopenshell::geom::util::split_solid_by_shell(i, s, a, b))) {
|
||||
slices.push_back(b);
|
||||
i = a;
|
||||
} else {
|
||||
@@ -167,7 +167,7 @@ namespace {
|
||||
}
|
||||
|
||||
|
||||
bool IfcGeom::util::apply_folded_layerset(const ConversionResults& items, const std::vector< std::vector<opencascade::handle<Geom_Surface>>>& surfaces, const std::vector<ifcopenshell::geometry::taxonomy::style::ptr>& styles, ConversionResults& result, double tol) {
|
||||
bool ifcopenshell::geom::util::apply_folded_layerset(const conversion_results& items, const std::vector< std::vector<opencascade::handle<Geom_Surface>>>& surfaces, const std::vector<ifcopenshell::geom::taxonomy::style::ptr>& styles, conversion_results& result, double tol) {
|
||||
Bnd_Box bb;
|
||||
TopoDS_Shape input;
|
||||
flatten_shape_list(items, input, false, false, tol);
|
||||
@@ -249,11 +249,11 @@ bool IfcGeom::util::apply_folded_layerset(const ConversionResults& items, const
|
||||
|
||||
} else if (shells.Extent() == 1) {
|
||||
|
||||
for (ConversionResults::const_iterator it = items.begin(); it != items.end(); ++it) {
|
||||
for (conversion_results::const_iterator it = items.begin(); it != items.end(); ++it) {
|
||||
TopoDS_Shape a, b;
|
||||
if (split_solid_by_shell(std::static_pointer_cast<OpenCascadeShape>(it->Shape())->shape(), shells.First(), a, b, tol)) {
|
||||
result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(b), (!!styles[0] ? styles[0] : it->StylePtr())));
|
||||
result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(a), (!!styles[1] ? styles[1] : it->StylePtr())));
|
||||
if (split_solid_by_shell(std::static_pointer_cast<open_cascade_shape>(it->Shape())->shape(), shells.First(), a, b, tol)) {
|
||||
result.push_back(conversion_result(it->ItemId(), it->Placement(), new open_cascade_shape(b), (!!styles[0] ? styles[0] : it->StylePtr())));
|
||||
result.push_back(conversion_result(it->ItemId(), it->Placement(), new open_cascade_shape(a), (!!styles[1] ? styles[1] : it->StylePtr())));
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
@@ -263,15 +263,15 @@ bool IfcGeom::util::apply_folded_layerset(const ConversionResults& items, const
|
||||
|
||||
} else {
|
||||
|
||||
for (ConversionResults::const_iterator it = items.begin(); it != items.end(); ++it) {
|
||||
for (conversion_results::const_iterator it = items.begin(); it != items.end(); ++it) {
|
||||
|
||||
const TopoDS_Shape& s = std::static_pointer_cast<OpenCascadeShape>(it->Shape())->shape();
|
||||
const TopoDS_Shape& s = std::static_pointer_cast<open_cascade_shape>(it->Shape())->shape();
|
||||
TopoDS_Shape sld = ensure_fit_for_subtraction(s, tol);
|
||||
|
||||
std::vector<TopoDS_Shape> slices;
|
||||
if (split(s, shells, tol, slices) && slices.size() == styles.size()) {
|
||||
for (size_t i = 0; i < slices.size(); ++i) {
|
||||
result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(slices[i]), (!!styles[i] ? styles[i] : it->StylePtr())));
|
||||
result.push_back(conversion_result(it->ItemId(), it->Placement(), new open_cascade_shape(slices[i]), (!!styles[i] ? styles[i] : it->StylePtr())));
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
@@ -284,18 +284,18 @@ bool IfcGeom::util::apply_folded_layerset(const ConversionResults& items, const
|
||||
|
||||
}
|
||||
|
||||
bool IfcGeom::util::apply_layerset(const ConversionResults& items, const std::vector<opencascade::handle<Geom_Surface>>& surfaces, const std::vector<ifcopenshell::geometry::taxonomy::style::ptr>& styles, ConversionResults& result, double tol) {
|
||||
bool ifcopenshell::geom::util::apply_layerset(const conversion_results& items, const std::vector<opencascade::handle<Geom_Surface>>& surfaces, const std::vector<ifcopenshell::geom::taxonomy::style::ptr>& styles, conversion_results& result, double tol) {
|
||||
if (surfaces.size() < 3) {
|
||||
|
||||
return false;
|
||||
|
||||
} else if (surfaces.size() == 3) {
|
||||
|
||||
for (ConversionResults::const_iterator it = items.begin(); it != items.end(); ++it) {
|
||||
for (conversion_results::const_iterator it = items.begin(); it != items.end(); ++it) {
|
||||
TopoDS_Shape a, b;
|
||||
if (split_solid_by_surface(std::static_pointer_cast<OpenCascadeShape>(it->Shape())->shape(), surfaces[1], a, b, tol)) {
|
||||
result.push_back(ConversionResult(it->ItemId(), it->Placement(),new OpenCascadeShape(b), (!!styles[0] ? styles[0] : it->StylePtr())));
|
||||
result.push_back(ConversionResult(it->ItemId(), it->Placement(),new OpenCascadeShape(a), (!!styles[1] ? styles[1] : it->StylePtr())));
|
||||
if (split_solid_by_surface(std::static_pointer_cast<open_cascade_shape>(it->Shape())->shape(), surfaces[1], a, b, tol)) {
|
||||
result.push_back(conversion_result(it->ItemId(), it->Placement(),new open_cascade_shape(b), (!!styles[0] ? styles[0] : it->StylePtr())));
|
||||
result.push_back(conversion_result(it->ItemId(), it->Placement(),new open_cascade_shape(a), (!!styles[1] ? styles[1] : it->StylePtr())));
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
@@ -309,7 +309,7 @@ bool IfcGeom::util::apply_layerset(const ConversionResults& items, const std::ve
|
||||
// Determine whether sequence of surfaces is consistent with surface normal, so that
|
||||
// layer operations are applied in the correct order. This seems to be always the case.
|
||||
Bnd_Box bb;
|
||||
for (ConversionResults::const_iterator it = items.begin(); it != items.end(); ++it) {
|
||||
for (conversion_results::const_iterator it = items.begin(); it != items.end(); ++it) {
|
||||
BRepBndLib::Add(it->Shape(), bb);
|
||||
}
|
||||
|
||||
@@ -334,9 +334,9 @@ bool IfcGeom::util::apply_layerset(const ConversionResults& items, const std::ve
|
||||
mass.ChangeCoord() += n1.XYZ();
|
||||
*/
|
||||
|
||||
for (ConversionResults::const_iterator it = items.begin(); it != items.end(); ++it) {
|
||||
for (conversion_results::const_iterator it = items.begin(); it != items.end(); ++it) {
|
||||
|
||||
const TopoDS_Shape& s = std::static_pointer_cast<OpenCascadeShape>(it->Shape())->shape();
|
||||
const TopoDS_Shape& s = std::static_pointer_cast<open_cascade_shape>(it->Shape())->shape();
|
||||
TopoDS_Shape sld = ensure_fit_for_subtraction(s, tol);
|
||||
|
||||
NCollection_List<TopoDS_Shape> operands;
|
||||
@@ -354,14 +354,14 @@ bool IfcGeom::util::apply_layerset(const ConversionResults& items, const std::ve
|
||||
/*
|
||||
// enable this is you want to see how IfcOpenShell has placed the layer surfaces
|
||||
for (auto& x : operands) {
|
||||
result.push_back(ConversionResult(it->ItemId(), it->Placement(), x, nullptr));
|
||||
result.push_back(conversion_result(it->ItemId(), it->Placement(), x, nullptr));
|
||||
}
|
||||
*/
|
||||
|
||||
std::vector<TopoDS_Shape> slices;
|
||||
if (split(s, operands, tol, slices) && slices.size() == styles.size()) {
|
||||
for (size_t i = 0; i < slices.size(); ++i) {
|
||||
result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(slices[i]), (!!styles[i] ? styles[i] : it->StylePtr())));
|
||||
result.push_back(conversion_result(it->ItemId(), it->Placement(), new open_cascade_shape(slices[i]), (!!styles[i] ? styles[i] : it->StylePtr())));
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
@@ -373,7 +373,7 @@ bool IfcGeom::util::apply_layerset(const ConversionResults& items, const std::ve
|
||||
}
|
||||
|
||||
|
||||
bool IfcGeom::util::split_solid_by_surface(const TopoDS_Shape& input, const opencascade::handle<Geom_Surface>& surface, TopoDS_Shape& front, TopoDS_Shape& back, double tol) {
|
||||
bool ifcopenshell::geom::util::split_solid_by_surface(const TopoDS_Shape& input, const opencascade::handle<Geom_Surface>& surface, TopoDS_Shape& front, TopoDS_Shape& back, double tol) {
|
||||
// Use an unbounded surface, that isolate part of the input shape,
|
||||
// to split this shape into two parts. Make sure that the addition
|
||||
// of the two result volumes matches that of the input.
|
||||
@@ -394,7 +394,7 @@ bool IfcGeom::util::split_solid_by_surface(const TopoDS_Shape& input, const open
|
||||
return b;
|
||||
}
|
||||
|
||||
bool IfcGeom::util::split_solid_by_shell(const TopoDS_Shape& input, const TopoDS_Shape& shell, TopoDS_Shape& front, TopoDS_Shape& back, double tol) {
|
||||
bool ifcopenshell::geom::util::split_solid_by_shell(const TopoDS_Shape& input, const TopoDS_Shape& shell, TopoDS_Shape& front, TopoDS_Shape& back, double tol) {
|
||||
// Use a shell, typically one or more connected faces, that isolate part
|
||||
// of the input shape, to split this shape into two parts. Make sure that
|
||||
// the addition of the two result volumes matches that of the input.
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
namespace IfcGeom {
|
||||
namespace ifcopenshell::geom {
|
||||
namespace util {
|
||||
bool apply_layerset(const ConversionResults&, const std::vector<opencascade::handle<Geom_Surface>>&, const std::vector<ifcopenshell::geometry::taxonomy::style::ptr>&, ConversionResults&, double tol);
|
||||
bool apply_layerset(const conversion_results&, const std::vector<opencascade::handle<Geom_Surface>>&, const std::vector<ifcopenshell::geom::taxonomy::style::ptr>&, conversion_results&, double tol);
|
||||
|
||||
bool apply_folded_layerset(const ConversionResults&, const std::vector<std::vector<opencascade::handle<Geom_Surface>>>&, const std::vector<ifcopenshell::geometry::taxonomy::style::ptr>&, ConversionResults&, double tol);
|
||||
bool apply_folded_layerset(const conversion_results&, const std::vector<std::vector<opencascade::handle<Geom_Surface>>>&, const std::vector<ifcopenshell::geom::taxonomy::style::ptr>&, conversion_results&, double tol);
|
||||
|
||||
bool split_solid_by_surface(const TopoDS_Shape&, const opencascade::handle<Geom_Surface>&, TopoDS_Shape&, TopoDS_Shape&, double tol);
|
||||
|
||||
@@ -21,4 +21,4 @@ namespace IfcGeom {
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -29,10 +29,9 @@
|
||||
#include <BRepBuilderAPI_MakeSolid.hxx>
|
||||
#include <BRepBuilderAPI_Transform.hxx>
|
||||
|
||||
using namespace ifcopenshell::geometry;
|
||||
using namespace ifcopenshell::geometry::kernels;
|
||||
using namespace IfcGeom;
|
||||
using namespace IfcGeom::util;
|
||||
using namespace ifcopenshell::geom;
|
||||
using namespace ifcopenshell::geom::kernels;
|
||||
using namespace ifcopenshell::geom::util;
|
||||
|
||||
// @todo duplicated
|
||||
namespace {
|
||||
@@ -55,7 +54,7 @@ bool has_intersection(const std::set<T, Cmp>& A,
|
||||
}
|
||||
}
|
||||
|
||||
bool OpenCascadeKernel::convert(const taxonomy::loft::ptr loft, TopoDS_Shape& result) {
|
||||
bool open_cascade_kernel::convert(const taxonomy::loft::ptr loft, TopoDS_Shape& result) {
|
||||
if (loft->children.size() < 2) {
|
||||
return false;
|
||||
}
|
||||
@@ -453,15 +452,15 @@ bool OpenCascadeKernel::convert(const taxonomy::loft::ptr loft, TopoDS_Shape& re
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenCascadeKernel::convert_impl(const taxonomy::loft::ptr loft, IfcGeom::ConversionResults& results) {
|
||||
bool open_cascade_kernel::convert_impl(const taxonomy::loft::ptr loft, ifcopenshell::geom::conversion_results& results) {
|
||||
TopoDS_Shape shape;
|
||||
if (!convert(loft, shape)) {
|
||||
return false;
|
||||
}
|
||||
results.emplace_back(ConversionResult(
|
||||
results.emplace_back(conversion_result(
|
||||
loft->instance.id(),
|
||||
loft->matrix,
|
||||
new OpenCascadeShape(shape),
|
||||
new open_cascade_shape(shape),
|
||||
loft->surface_style
|
||||
));
|
||||
return true;
|
||||
|
||||
@@ -26,17 +26,16 @@
|
||||
#include <BRepAdaptor_HCompCurve.hxx>
|
||||
#endif
|
||||
|
||||
using namespace ifcopenshell::geometry;
|
||||
using namespace ifcopenshell::geometry::kernels;
|
||||
using namespace IfcGeom;
|
||||
using namespace IfcGeom::util;
|
||||
using namespace ifcopenshell::geom;
|
||||
using namespace ifcopenshell::geom::kernels;
|
||||
using namespace ifcopenshell::geom::util;
|
||||
|
||||
namespace {
|
||||
struct curve_creation_visitor {
|
||||
OpenCascadeKernel* kernel;
|
||||
OpenCascadeKernel::curve_creation_visitor_result_type result;
|
||||
open_cascade_kernel* kernel;
|
||||
open_cascade_kernel::curve_creation_visitor_result_type result;
|
||||
|
||||
OpenCascadeKernel::curve_creation_visitor_result_type operator()(const taxonomy::bspline_curve::ptr& bc) {
|
||||
open_cascade_kernel::curve_creation_visitor_result_type operator()(const taxonomy::bspline_curve::ptr& bc) {
|
||||
|
||||
const bool is_rational = !!bc->weights;
|
||||
|
||||
@@ -60,7 +59,7 @@ namespace {
|
||||
|
||||
i = 0;
|
||||
for (auto it = bc->control_points.begin(); it != bc->control_points.end(); ++it, ++i) {
|
||||
Poles(i) = OpenCascadeKernel::convert_xyz<gp_Pnt>(**it);
|
||||
Poles(i) = open_cascade_kernel::convert_xyz<gp_Pnt>(**it);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
@@ -80,22 +79,22 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
OpenCascadeKernel::curve_creation_visitor_result_type operator()(const taxonomy::line::ptr& l) {
|
||||
open_cascade_kernel::curve_creation_visitor_result_type operator()(const taxonomy::line::ptr& l) {
|
||||
const auto& m = l->matrix->ccomponents();
|
||||
return result = Handle(Geom_Curve)(new Geom_Line(OpenCascadeKernel::convert_xyz2<gp_Pnt>(m.col(3)), OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(2))));
|
||||
return result = Handle(Geom_Curve)(new Geom_Line(open_cascade_kernel::convert_xyz2<gp_Pnt>(m.col(3)), open_cascade_kernel::convert_xyz2<gp_Dir>(m.col(2))));
|
||||
}
|
||||
|
||||
OpenCascadeKernel::curve_creation_visitor_result_type operator()(const taxonomy::circle::ptr& c) {
|
||||
open_cascade_kernel::curve_creation_visitor_result_type operator()(const taxonomy::circle::ptr& c) {
|
||||
const auto& m = c->matrix->ccomponents();
|
||||
return result = Handle(Geom_Curve)(new Geom_Circle(gp_Ax2(OpenCascadeKernel::convert_xyz2<gp_Pnt>(m.col(3)), OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(2)), OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(0))), c->radius));
|
||||
return result = Handle(Geom_Curve)(new Geom_Circle(gp_Ax2(open_cascade_kernel::convert_xyz2<gp_Pnt>(m.col(3)), open_cascade_kernel::convert_xyz2<gp_Dir>(m.col(2)), open_cascade_kernel::convert_xyz2<gp_Dir>(m.col(0))), c->radius));
|
||||
}
|
||||
|
||||
OpenCascadeKernel::curve_creation_visitor_result_type operator()(const taxonomy::ellipse::ptr& e) {
|
||||
open_cascade_kernel::curve_creation_visitor_result_type operator()(const taxonomy::ellipse::ptr& e) {
|
||||
const auto& m = e->matrix->ccomponents();
|
||||
return result = Handle(Geom_Curve)(new Geom_Ellipse(gp_Ax2(OpenCascadeKernel::convert_xyz2<gp_Pnt>(m.col(3)), OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(2)), OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(0))), e->radius, e->radius2));
|
||||
return result = Handle(Geom_Curve)(new Geom_Ellipse(gp_Ax2(open_cascade_kernel::convert_xyz2<gp_Pnt>(m.col(3)), open_cascade_kernel::convert_xyz2<gp_Dir>(m.col(2)), open_cascade_kernel::convert_xyz2<gp_Dir>(m.col(0))), e->radius, e->radius2));
|
||||
}
|
||||
|
||||
OpenCascadeKernel::curve_creation_visitor_result_type operator()(const taxonomy::loop::ptr& l) {
|
||||
open_cascade_kernel::curve_creation_visitor_result_type operator()(const taxonomy::loop::ptr& l) {
|
||||
TopoDS_Wire wire;
|
||||
if (!kernel->convert(l, wire)) {
|
||||
throw std::runtime_error("Failed to convert loop to wire");
|
||||
@@ -103,7 +102,7 @@ namespace {
|
||||
return result = wire;
|
||||
}
|
||||
|
||||
OpenCascadeKernel::curve_creation_visitor_result_type operator()(const taxonomy::edge::ptr& e) {
|
||||
open_cascade_kernel::curve_creation_visitor_result_type operator()(const taxonomy::edge::ptr& e) {
|
||||
// @todo for polyloops/-lines we should probably construct edges based on correct oriented TopoDS_Vertex instead.
|
||||
|
||||
if (e->start.index() != e->end.index()) {
|
||||
@@ -156,8 +155,8 @@ namespace {
|
||||
if (e_start.index() == 0) {
|
||||
E = BRepBuilderAPI_MakeEdge(curve).Edge();
|
||||
} else if (e_start.index() == 1) {
|
||||
auto p1 = OpenCascadeKernel::convert_xyz<gp_Pnt>(*std::get<taxonomy::point3::ptr>(e_start));
|
||||
auto p2 = OpenCascadeKernel::convert_xyz<gp_Pnt>(*std::get<taxonomy::point3::ptr>(e_end));
|
||||
auto p1 = open_cascade_kernel::convert_xyz<gp_Pnt>(*std::get<taxonomy::point3::ptr>(e_start));
|
||||
auto p2 = open_cascade_kernel::convert_xyz<gp_Pnt>(*std::get<taxonomy::point3::ptr>(e_end));
|
||||
|
||||
if (curve->IsClosed() && p1.Distance(p2) <= kernel->settings().get<settings::Precision>().get()) {
|
||||
E = BRepBuilderAPI_MakeEdge(curve).Edge();
|
||||
@@ -186,8 +185,8 @@ namespace {
|
||||
if (e->start.index() != 1) {
|
||||
throw std::runtime_error("Non-cartesian trim on edge without curve");
|
||||
}
|
||||
auto p1 = OpenCascadeKernel::convert_xyz<gp_Pnt>(*std::get<taxonomy::point3::ptr>(e->start));
|
||||
auto p2 = OpenCascadeKernel::convert_xyz<gp_Pnt>(*std::get<taxonomy::point3::ptr>(e->end));
|
||||
auto p1 = open_cascade_kernel::convert_xyz<gp_Pnt>(*std::get<taxonomy::point3::ptr>(e->start));
|
||||
auto p2 = open_cascade_kernel::convert_xyz<gp_Pnt>(*std::get<taxonomy::point3::ptr>(e->end));
|
||||
|
||||
E = BRepBuilderAPI_MakeEdge(p1, p2).Edge();
|
||||
}
|
||||
@@ -214,7 +213,7 @@ namespace {
|
||||
return result = W;
|
||||
}
|
||||
|
||||
OpenCascadeKernel::curve_creation_visitor_result_type operator()(const taxonomy::offset_curve::ptr&) {
|
||||
open_cascade_kernel::curve_creation_visitor_result_type operator()(const taxonomy::offset_curve::ptr&) {
|
||||
// @todo
|
||||
throw std::runtime_error("Offset curves not supported as part of loop");
|
||||
}
|
||||
@@ -222,7 +221,7 @@ namespace {
|
||||
|
||||
}
|
||||
|
||||
OpenCascadeKernel::curve_creation_visitor_result_type OpenCascadeKernel::convert_curve(const taxonomy::ptr curve) {
|
||||
open_cascade_kernel::curve_creation_visitor_result_type open_cascade_kernel::convert_curve(const taxonomy::ptr curve) {
|
||||
curve_creation_visitor v{ this };
|
||||
if (dispatch_curve_creation<curve_creation_visitor, 0>::dispatch(curve, v)) {
|
||||
return v.result;
|
||||
@@ -233,7 +232,7 @@ OpenCascadeKernel::curve_creation_visitor_result_type OpenCascadeKernel::convert
|
||||
|
||||
#include "../../../ifcparse/file.h"
|
||||
|
||||
bool OpenCascadeKernel::convert(const taxonomy::loop::ptr loop, TopoDS_Wire& wire) {
|
||||
bool open_cascade_kernel::convert(const taxonomy::loop::ptr loop, TopoDS_Wire& wire) {
|
||||
NCollection_List<TopoDS_Shape> converted_segments;
|
||||
|
||||
/*
|
||||
@@ -294,14 +293,14 @@ bool OpenCascadeKernel::convert(const taxonomy::loop::ptr loop, TopoDS_Wire& wir
|
||||
NCollection_List<TopoDS_Shape>::Iterator it(converted_segments);
|
||||
|
||||
bool force_close = false;
|
||||
if (loop->instance && loop->instance.as<express::Entity>()) {
|
||||
auto inst = loop->instance.as<express::Entity>();
|
||||
auto file = loop->instance.as<express::Entity>().file();
|
||||
if (loop->instance && loop->instance.as<express::entity>()) {
|
||||
auto inst = loop->instance.as<express::entity>();
|
||||
auto file = loop->instance.as<express::entity>().file();
|
||||
auto profile = file->get_inverse(inst.id(), file->schema()->declaration_by_name("IfcProfileDef"), -1);
|
||||
force_close = profile.size() > 0;
|
||||
}
|
||||
|
||||
wire_builder bld(precision_, loop->instance ? loop->instance.as<express::Entity>() : express::Base{});
|
||||
wire_builder bld(precision_, loop->instance ? loop->instance.as<express::entity>() : express::base{});
|
||||
shape_pair_enumerate(it, bld, force_close);
|
||||
wire = bld.wire();
|
||||
|
||||
@@ -395,26 +394,26 @@ bool OpenCascadeKernel::convert(const taxonomy::loop::ptr loop, TopoDS_Wire& wir
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenCascadeKernel::convert_impl(const taxonomy::loop::ptr loop, IfcGeom::ConversionResults& results) {
|
||||
bool open_cascade_kernel::convert_impl(const taxonomy::loop::ptr loop, ifcopenshell::geom::conversion_results& results) {
|
||||
TopoDS_Wire shape;
|
||||
if (!convert(loop, shape)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
results.emplace_back(ConversionResult(
|
||||
results.emplace_back(conversion_result(
|
||||
loop->instance.id(),
|
||||
new OpenCascadeShape(shape),
|
||||
new open_cascade_shape(shape),
|
||||
loop->surface_style
|
||||
));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenCascadeKernel::convert_impl(const taxonomy::edge::ptr edge, IfcGeom::ConversionResults& results) {
|
||||
bool open_cascade_kernel::convert_impl(const taxonomy::edge::ptr edge, ifcopenshell::geom::conversion_results& results) {
|
||||
TopoDS_Wire shape = std::get<TopoDS_Wire>(convert_curve(edge));
|
||||
|
||||
results.emplace_back(ConversionResult(
|
||||
results.emplace_back(conversion_result(
|
||||
edge->instance.id(),
|
||||
new OpenCascadeShape(shape),
|
||||
new open_cascade_shape(shape),
|
||||
edge->surface_style
|
||||
));
|
||||
return true;
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
#include "OpenCascadeKernel.h"
|
||||
|
||||
using namespace ifcopenshell::geometry;
|
||||
using namespace ifcopenshell::geometry::kernels;
|
||||
using namespace IfcGeom;
|
||||
using namespace IfcGeom::util;
|
||||
using namespace ifcopenshell::geom;
|
||||
using namespace ifcopenshell::geom::kernels;
|
||||
using namespace ifcopenshell::geom::util;
|
||||
|
||||
bool OpenCascadeKernel::convert(const taxonomy::matrix4::ptr matrix, gp_GTrsf& trsf) {
|
||||
bool open_cascade_kernel::convert(const taxonomy::matrix4::ptr matrix, gp_GTrsf& trsf) {
|
||||
// @todo check
|
||||
const auto& m = matrix->ccomponents();
|
||||
gp_Mat mat(
|
||||
@@ -43,4 +42,4 @@ bool OpenCascadeKernel::convert(const taxonomy::matrix4::ptr matrix, gp_GTrsf& t
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <boost/dll/alias.hpp>
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace geometry {
|
||||
namespace geom {
|
||||
namespace kernels {
|
||||
namespace opencascade_plugin {
|
||||
|
||||
@@ -35,8 +35,8 @@ namespace ifcopenshell {
|
||||
return kernel_plugin_metadata("opencascade");
|
||||
}
|
||||
|
||||
AbstractKernel* create_kernel(ifcopenshell::file*, Settings& settings) {
|
||||
return new IfcGeom::OpenCascadeKernel(settings);
|
||||
abstract_kernel* create_kernel(ifcopenshell::file*, ifcopenshell::geom::settings& settings) {
|
||||
return new ifcopenshell::geom::open_cascade_kernel(settings);
|
||||
}
|
||||
|
||||
void register_plugin(kernel_registry& registry, const plugin::module& module) {
|
||||
@@ -51,6 +51,6 @@ namespace ifcopenshell {
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geometry::kernels::opencascade_plugin::plugin_abi, ifcopenshell_plugin_abi_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geometry::kernels::opencascade_plugin::plugin_metadata, ifcopenshell_plugin_metadata_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geometry::kernels::opencascade_plugin::register_plugin, ifcopenshell_register_kernel_plugin_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geom::kernels::opencascade_plugin::plugin_abi, ifcopenshell_plugin_abi_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geom::kernels::opencascade_plugin::plugin_metadata, ifcopenshell_plugin_metadata_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geom::kernels::opencascade_plugin::register_plugin, ifcopenshell_register_kernel_plugin_v1)
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
|
||||
#include "base_utils.h"
|
||||
|
||||
using namespace ifcopenshell::geometry;
|
||||
using namespace ifcopenshell::geometry::kernels;
|
||||
using namespace IfcGeom;
|
||||
using namespace IfcGeom::util;
|
||||
using namespace ifcopenshell::geom;
|
||||
using namespace ifcopenshell::geom::kernels;
|
||||
using namespace ifcopenshell::geom::util;
|
||||
|
||||
namespace {
|
||||
// @todo move into taxonomy;
|
||||
@@ -24,7 +23,7 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
bool OpenCascadeKernel::convert(const taxonomy::shell::ptr l, TopoDS_Shape& shape) {
|
||||
bool open_cascade_kernel::convert(const taxonomy::shell::ptr l, TopoDS_Shape& shape) {
|
||||
std::unique_ptr<faceset_helper> helper_scope;
|
||||
if (shell_polyhedral(l)) {
|
||||
helper_scope.reset(new faceset_helper(this, l));
|
||||
@@ -106,17 +105,17 @@ bool OpenCascadeKernel::convert(const taxonomy::shell::ptr l, TopoDS_Shape& shap
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenCascadeKernel::convert_impl(const taxonomy::shell::ptr shell, IfcGeom::ConversionResults& results) {
|
||||
bool open_cascade_kernel::convert_impl(const taxonomy::shell::ptr shell, ifcopenshell::geom::conversion_results& results) {
|
||||
return handle_occt_exception([&]() -> bool {
|
||||
|
||||
TopoDS_Shape shape;
|
||||
if (!convert(shell, shape)) {
|
||||
return false;
|
||||
}
|
||||
results.emplace_back(ConversionResult(
|
||||
results.emplace_back(conversion_result(
|
||||
shell->instance.id(),
|
||||
shell->matrix,
|
||||
new OpenCascadeShape(shape),
|
||||
new open_cascade_shape(shape),
|
||||
shell->surface_style
|
||||
));
|
||||
return true;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user