mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-12 10:33:20 +00:00
draw.py use settings instead of direct member methods
This commit is contained in:
@@ -141,6 +141,12 @@ inline namespace settings {
|
||||
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.";
|
||||
@@ -164,12 +170,23 @@ inline namespace settings {
|
||||
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.";
|
||||
@@ -194,6 +211,18 @@ inline namespace settings {
|
||||
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.";
|
||||
@@ -251,15 +280,20 @@ class SerializerSettings : public SettingsContainer <
|
||||
SvgAutoSection,
|
||||
SvgAutoElevation,
|
||||
SvgDrawStoreyHeights,
|
||||
SvgProfileThreshold,
|
||||
SvgStoreyHeightLineLength,
|
||||
SvgUseNamespace,
|
||||
SvgUseHlrPoly,
|
||||
SvgUsePrefiltering,
|
||||
SvgUnifyInputs,
|
||||
SvgSegmentProjection,
|
||||
SvgSubtractBefore,
|
||||
SvgPolygonal,
|
||||
SvgAlwaysProject,
|
||||
SvgWithoutStoreys,
|
||||
SvgNoCss,
|
||||
SvgMirrorY,
|
||||
SvgMirrorX,
|
||||
SvgDoorArcs,
|
||||
SvgSectionHeight,
|
||||
SvgSectionHeightFromStoreys,
|
||||
|
||||
@@ -159,52 +159,49 @@ def main(
|
||||
# Initialize serializer
|
||||
buffer = ifcopenshell.geom.serializers.buffer()
|
||||
serialiser_settings = ifcopenshell.geom.serializer_settings()
|
||||
sr = ifcopenshell.geom.serializers.svg(buffer, geom_settings, serialiser_settings)
|
||||
|
||||
sr.setFile(files[0])
|
||||
if settings.auto_floorplan:
|
||||
sr.setSectionHeightsFromStoreys()
|
||||
serialiser_settings.set("section-height-from-storeys", True)
|
||||
|
||||
# setElevationRefGuid and setElevationRef are also mutually exclusive in C-code.
|
||||
# elevation-ref-guid and elevation-ref are also mutually exclusive in C-code.
|
||||
# Note that guid or object type are not checked anywhere to be valid,
|
||||
# it's up to user to keep them valid for the provided projects.
|
||||
if settings.drawing_guid or settings.drawing_object_type:
|
||||
if settings.drawing_guid:
|
||||
if not by_guid(settings.drawing_guid):
|
||||
raise ValueError(f"Unable to find guid {settings.drawing_guid!r}")
|
||||
sr.setElevationRefGuid(settings.drawing_guid)
|
||||
serialiser_settings.set("elevation-ref-guid", settings.drawing_guid)
|
||||
elif settings.drawing_object_type:
|
||||
sr.setElevationRef(settings.drawing_object_type)
|
||||
sr.setWithoutStoreys(True)
|
||||
serialiser_settings.set("elevation-ref", settings.drawing_object_type)
|
||||
serialiser_settings.set("svg-without-storeys", True)
|
||||
|
||||
# required for svgfill
|
||||
sr.setPolygonal(True)
|
||||
sr.setUseNamespace(True)
|
||||
serialiser_settings.set("svg-write-poly", True)
|
||||
serialiser_settings.set("svg-xmlns", True)
|
||||
|
||||
sr.setAlwaysProject(settings.include_projection)
|
||||
|
||||
sr.setProfileThreshold(settings.profile_threshold)
|
||||
sr.setBoundingRectangle(settings.width, settings.height)
|
||||
sr.setScale(settings.scale)
|
||||
sr.setAutoElevation(settings.auto_elevation)
|
||||
sr.setAutoSection(settings.auto_section)
|
||||
sr.setPrintSpaceNames(settings.space_names)
|
||||
sr.setPrintSpaceAreas(settings.space_areas)
|
||||
sr.setDrawDoorArcs(settings.door_arcs)
|
||||
sr.setNoCSS(not not settings.css)
|
||||
serialiser_settings.set("svg-project", settings.include_projection)
|
||||
serialiser_settings.set("profile-threshold", settings.profile_threshold)
|
||||
serialiser_settings.set("bounds", f"{settings.width}x{settings.height}")
|
||||
serialiser_settings.set("scale", str(settings.scale))
|
||||
serialiser_settings.set("auto-elevation", settings.auto_elevation)
|
||||
serialiser_settings.set("auto-section", settings.auto_section)
|
||||
serialiser_settings.set("print-space-names", settings.space_names)
|
||||
serialiser_settings.set("print-space-areas", settings.space_areas)
|
||||
serialiser_settings.set("door-arcs", settings.door_arcs)
|
||||
serialiser_settings.set("svg-no-css", bool(settings.css))
|
||||
if settings.subtract_before_hlr:
|
||||
sr.setSubtractionSettings(W.ALWAYS)
|
||||
serialiser_settings.set("svg-subtract-before", "always")
|
||||
|
||||
sr.setUseHlrPoly(settings.hlr_poly)
|
||||
sr.setUsePrefiltering(settings.prefilter)
|
||||
sr.setUnifyInputs(settings.unify_inputs)
|
||||
sr.setMirrorY(settings.mirror_y)
|
||||
serialiser_settings.set("svg-poly", settings.hlr_poly)
|
||||
serialiser_settings.set("svg-prefilter", settings.prefilter)
|
||||
serialiser_settings.set("svg-unify-inputs", settings.unify_inputs)
|
||||
serialiser_settings.set("svg-mirror-y", settings.mirror_y)
|
||||
|
||||
try:
|
||||
sh = ["none", "full", "left"].index(settings.storey_heights)
|
||||
sr.setDrawStoreyHeights(sh)
|
||||
except:
|
||||
if settings.storey_heights not in {"none", "full", "left"}:
|
||||
raise ValueError("storey_heights should be one of {'none', 'full', 'left'}")
|
||||
serialiser_settings.set("draw-storey-heights", settings.storey_heights)
|
||||
|
||||
sr = ifcopenshell.geom.serializers.svg(buffer, geom_settings, serialiser_settings)
|
||||
sr.setFile(files[0])
|
||||
|
||||
"""
|
||||
# It is also possible to add drawing planes manually
|
||||
|
||||
@@ -97,10 +97,10 @@ namespace {
|
||||
const double PI2 = M_PI * 2.;
|
||||
|
||||
std::pair<double, double> parse_svg_bounds(const std::string& value) {
|
||||
unsigned int width = 0;
|
||||
unsigned int height = 0;
|
||||
if (std::sscanf(value.c_str(), "%ux%u", &width, &height) == 2 && width > 0 && height > 0) {
|
||||
return { static_cast<double>(width), static_cast<double>(height) };
|
||||
double width = 0.;
|
||||
double height = 0.;
|
||||
if (std::sscanf(value.c_str(), "%lfx%lf", &width, &height) == 2 && width > 0. && height > 0.) {
|
||||
return { width, height };
|
||||
}
|
||||
throw std::runtime_error("Invalid use of --bounds");
|
||||
}
|
||||
@@ -123,9 +123,27 @@ double parse_svg_scale(const std::string& value) {
|
||||
numerator > 0 && denominator > 0) {
|
||||
return static_cast<double>(numerator) / denominator;
|
||||
}
|
||||
double scale = 0.;
|
||||
if (std::sscanf(value.c_str(), "%lf", &scale) == 1 && scale > 0.) {
|
||||
return scale;
|
||||
}
|
||||
throw std::runtime_error("Invalid use of --scale");
|
||||
}
|
||||
|
||||
subtract_before_project parse_subtract_before_project(const std::string& value) {
|
||||
const auto setting = boost::to_lower_copy(value);
|
||||
if (setting == "auto" || setting == "slabs-at-floorplans" || setting == "slabs-at-floor-plans") {
|
||||
return ON_SLABS_AT_FLOORPLANS;
|
||||
}
|
||||
if (setting == "slabs-and-walls") {
|
||||
return ON_SLABS_AND_WALLS;
|
||||
}
|
||||
if (setting == "always") {
|
||||
return ALWAYS;
|
||||
}
|
||||
throw std::runtime_error("Invalid use of --svg-subtract-before, expected auto|slabs-and-walls|always");
|
||||
}
|
||||
|
||||
SvgSerializer::storey_height_display_types parse_storey_height_display(const std::string& value) {
|
||||
const auto display = boost::to_lower_copy(value);
|
||||
if (display == "none") {
|
||||
@@ -163,7 +181,7 @@ void SvgSerializer::apply_settings() {
|
||||
setDrawingCenter(center.first, center.second);
|
||||
}
|
||||
|
||||
if (settings().get<SvgSectionHeightFromStoreys>().get()) {
|
||||
if (settings().get<SvgSectionHeightFromStoreys>().get() && file) {
|
||||
if (settings().get<SvgSectionHeight>().has()) {
|
||||
setSectionHeightsFromStoreys(settings().get<SvgSectionHeight>().get());
|
||||
} else {
|
||||
@@ -181,11 +199,19 @@ void SvgSerializer::apply_settings() {
|
||||
setUseNamespace(settings().get<SvgUseNamespace>().get());
|
||||
setUseHlrPoly(settings().get<SvgUseHlrPoly>().get());
|
||||
setUsePrefiltering(settings().get<SvgUsePrefiltering>().get());
|
||||
setUnifyInputs(settings().get<SvgUnifyInputs>().get());
|
||||
setSegmentProjection(settings().get<SvgSegmentProjection>().get());
|
||||
setPolygonal(settings().get<SvgPolygonal>().get());
|
||||
setAlwaysProject(settings().get<SvgAlwaysProject>().get());
|
||||
setWithoutStoreys(settings().get<SvgWithoutStoreys>().get());
|
||||
setNoCSS(settings().get<SvgNoCss>().get());
|
||||
setMirrorY(settings().get<SvgMirrorY>().get());
|
||||
setMirrorX(settings().get<SvgMirrorX>().get());
|
||||
setProfileThreshold(settings().get<SvgProfileThreshold>().get());
|
||||
|
||||
if (settings().get<SvgSubtractBefore>().has()) {
|
||||
setSubtractionSettings(parse_subtract_before_project(settings().get<SvgSubtractBefore>().get()));
|
||||
}
|
||||
|
||||
if (settings().get<SvgDrawStoreyHeights>().has()) {
|
||||
setDrawStoreyHeights(parse_storey_height_display(settings().get<SvgDrawStoreyHeights>().get()));
|
||||
@@ -2425,7 +2451,18 @@ std::string SvgSerializer::nameElement(express::Base elem_) {
|
||||
}
|
||||
|
||||
void SvgSerializer::setFile(ifcopenshell::file* f) {
|
||||
using namespace ifcopenshell::geometry::settings;
|
||||
|
||||
file = f;
|
||||
auto apply_section_heights_from_storeys = [&]() {
|
||||
if (settings().get<SvgSectionHeightFromStoreys>().get()) {
|
||||
if (settings().get<SvgSectionHeight>().has()) {
|
||||
setSectionHeightsFromStoreys(settings().get<SvgSectionHeight>().get());
|
||||
} else {
|
||||
setSectionHeightsFromStoreys();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
auto storeys = f->instances_by_type("IfcBuildingStorey");
|
||||
if (storeys.empty()) {
|
||||
@@ -2449,6 +2486,7 @@ void SvgSerializer::setFile(ifcopenshell::file* f) {
|
||||
delete matrix;
|
||||
#endif
|
||||
logger::warning("No building storeys encountered, used for reference:", product);
|
||||
apply_section_heights_from_storeys();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -2459,6 +2497,8 @@ void SvgSerializer::setFile(ifcopenshell::file* f) {
|
||||
|
||||
logger::warning("No building storeys encountered, output might be invalid or missing");
|
||||
}
|
||||
|
||||
apply_section_heights_from_storeys();
|
||||
}
|
||||
|
||||
void SvgSerializer::setSectionHeight(double h, express::Base storey) {
|
||||
|
||||
Reference in New Issue
Block a user