mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-26 10:11:46 +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.";
|
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> {
|
struct SvgStoreyHeightLineLength : public SettingBase<SvgStoreyHeightLineLength, double> {
|
||||||
static constexpr const char* const name = "storey-height-line-length";
|
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.";
|
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;
|
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> {
|
struct SvgSegmentProjection : public SettingBase<SvgSegmentProjection, bool> {
|
||||||
static constexpr const char* const name = "svg-segment-projection";
|
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 const char* const description = "Segment result of projection with respect to original products.";
|
||||||
static constexpr bool defaultvalue = false;
|
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> {
|
struct SvgPolygonal : public SettingBase<SvgPolygonal, bool> {
|
||||||
static constexpr const char* const name = "svg-write-poly";
|
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 const char* const description = "Approximate every curve as polygonal in SVG output.";
|
||||||
@@ -194,6 +211,18 @@ inline namespace settings {
|
|||||||
static constexpr bool defaultvalue = false;
|
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> {
|
struct SvgDoorArcs : public SettingBase<SvgDoorArcs, bool> {
|
||||||
static constexpr const char* const name = "door-arcs";
|
static constexpr const char* const name = "door-arcs";
|
||||||
static constexpr const char* const description = "Draw door opening arcs for IfcDoor elements.";
|
static constexpr const char* const description = "Draw door opening arcs for IfcDoor elements.";
|
||||||
@@ -251,15 +280,20 @@ class SerializerSettings : public SettingsContainer <
|
|||||||
SvgAutoSection,
|
SvgAutoSection,
|
||||||
SvgAutoElevation,
|
SvgAutoElevation,
|
||||||
SvgDrawStoreyHeights,
|
SvgDrawStoreyHeights,
|
||||||
|
SvgProfileThreshold,
|
||||||
SvgStoreyHeightLineLength,
|
SvgStoreyHeightLineLength,
|
||||||
SvgUseNamespace,
|
SvgUseNamespace,
|
||||||
SvgUseHlrPoly,
|
SvgUseHlrPoly,
|
||||||
SvgUsePrefiltering,
|
SvgUsePrefiltering,
|
||||||
|
SvgUnifyInputs,
|
||||||
SvgSegmentProjection,
|
SvgSegmentProjection,
|
||||||
|
SvgSubtractBefore,
|
||||||
SvgPolygonal,
|
SvgPolygonal,
|
||||||
SvgAlwaysProject,
|
SvgAlwaysProject,
|
||||||
SvgWithoutStoreys,
|
SvgWithoutStoreys,
|
||||||
SvgNoCss,
|
SvgNoCss,
|
||||||
|
SvgMirrorY,
|
||||||
|
SvgMirrorX,
|
||||||
SvgDoorArcs,
|
SvgDoorArcs,
|
||||||
SvgSectionHeight,
|
SvgSectionHeight,
|
||||||
SvgSectionHeightFromStoreys,
|
SvgSectionHeightFromStoreys,
|
||||||
|
|||||||
@@ -159,52 +159,49 @@ def main(
|
|||||||
# Initialize serializer
|
# Initialize serializer
|
||||||
buffer = ifcopenshell.geom.serializers.buffer()
|
buffer = ifcopenshell.geom.serializers.buffer()
|
||||||
serialiser_settings = ifcopenshell.geom.serializer_settings()
|
serialiser_settings = ifcopenshell.geom.serializer_settings()
|
||||||
sr = ifcopenshell.geom.serializers.svg(buffer, geom_settings, serialiser_settings)
|
|
||||||
|
|
||||||
sr.setFile(files[0])
|
|
||||||
if settings.auto_floorplan:
|
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,
|
# 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.
|
# 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 or settings.drawing_object_type:
|
||||||
if settings.drawing_guid:
|
if settings.drawing_guid:
|
||||||
if not by_guid(settings.drawing_guid):
|
if not by_guid(settings.drawing_guid):
|
||||||
raise ValueError(f"Unable to find guid {settings.drawing_guid!r}")
|
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:
|
elif settings.drawing_object_type:
|
||||||
sr.setElevationRef(settings.drawing_object_type)
|
serialiser_settings.set("elevation-ref", settings.drawing_object_type)
|
||||||
sr.setWithoutStoreys(True)
|
serialiser_settings.set("svg-without-storeys", True)
|
||||||
|
|
||||||
# required for svgfill
|
# required for svgfill
|
||||||
sr.setPolygonal(True)
|
serialiser_settings.set("svg-write-poly", True)
|
||||||
sr.setUseNamespace(True)
|
serialiser_settings.set("svg-xmlns", True)
|
||||||
|
|
||||||
sr.setAlwaysProject(settings.include_projection)
|
serialiser_settings.set("svg-project", settings.include_projection)
|
||||||
|
serialiser_settings.set("profile-threshold", settings.profile_threshold)
|
||||||
sr.setProfileThreshold(settings.profile_threshold)
|
serialiser_settings.set("bounds", f"{settings.width}x{settings.height}")
|
||||||
sr.setBoundingRectangle(settings.width, settings.height)
|
serialiser_settings.set("scale", str(settings.scale))
|
||||||
sr.setScale(settings.scale)
|
serialiser_settings.set("auto-elevation", settings.auto_elevation)
|
||||||
sr.setAutoElevation(settings.auto_elevation)
|
serialiser_settings.set("auto-section", settings.auto_section)
|
||||||
sr.setAutoSection(settings.auto_section)
|
serialiser_settings.set("print-space-names", settings.space_names)
|
||||||
sr.setPrintSpaceNames(settings.space_names)
|
serialiser_settings.set("print-space-areas", settings.space_areas)
|
||||||
sr.setPrintSpaceAreas(settings.space_areas)
|
serialiser_settings.set("door-arcs", settings.door_arcs)
|
||||||
sr.setDrawDoorArcs(settings.door_arcs)
|
serialiser_settings.set("svg-no-css", bool(settings.css))
|
||||||
sr.setNoCSS(not not settings.css)
|
|
||||||
if settings.subtract_before_hlr:
|
if settings.subtract_before_hlr:
|
||||||
sr.setSubtractionSettings(W.ALWAYS)
|
serialiser_settings.set("svg-subtract-before", "always")
|
||||||
|
|
||||||
sr.setUseHlrPoly(settings.hlr_poly)
|
serialiser_settings.set("svg-poly", settings.hlr_poly)
|
||||||
sr.setUsePrefiltering(settings.prefilter)
|
serialiser_settings.set("svg-prefilter", settings.prefilter)
|
||||||
sr.setUnifyInputs(settings.unify_inputs)
|
serialiser_settings.set("svg-unify-inputs", settings.unify_inputs)
|
||||||
sr.setMirrorY(settings.mirror_y)
|
serialiser_settings.set("svg-mirror-y", settings.mirror_y)
|
||||||
|
|
||||||
try:
|
if settings.storey_heights not in {"none", "full", "left"}:
|
||||||
sh = ["none", "full", "left"].index(settings.storey_heights)
|
|
||||||
sr.setDrawStoreyHeights(sh)
|
|
||||||
except:
|
|
||||||
raise ValueError("storey_heights should be one of {'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
|
# It is also possible to add drawing planes manually
|
||||||
|
|||||||
@@ -97,10 +97,10 @@ namespace {
|
|||||||
const double PI2 = M_PI * 2.;
|
const double PI2 = M_PI * 2.;
|
||||||
|
|
||||||
std::pair<double, double> parse_svg_bounds(const std::string& value) {
|
std::pair<double, double> parse_svg_bounds(const std::string& value) {
|
||||||
unsigned int width = 0;
|
double width = 0.;
|
||||||
unsigned int height = 0;
|
double height = 0.;
|
||||||
if (std::sscanf(value.c_str(), "%ux%u", &width, &height) == 2 && width > 0 && height > 0) {
|
if (std::sscanf(value.c_str(), "%lfx%lf", &width, &height) == 2 && width > 0. && height > 0.) {
|
||||||
return { static_cast<double>(width), static_cast<double>(height) };
|
return { width, height };
|
||||||
}
|
}
|
||||||
throw std::runtime_error("Invalid use of --bounds");
|
throw std::runtime_error("Invalid use of --bounds");
|
||||||
}
|
}
|
||||||
@@ -123,9 +123,27 @@ double parse_svg_scale(const std::string& value) {
|
|||||||
numerator > 0 && denominator > 0) {
|
numerator > 0 && denominator > 0) {
|
||||||
return static_cast<double>(numerator) / denominator;
|
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");
|
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) {
|
SvgSerializer::storey_height_display_types parse_storey_height_display(const std::string& value) {
|
||||||
const auto display = boost::to_lower_copy(value);
|
const auto display = boost::to_lower_copy(value);
|
||||||
if (display == "none") {
|
if (display == "none") {
|
||||||
@@ -163,7 +181,7 @@ void SvgSerializer::apply_settings() {
|
|||||||
setDrawingCenter(center.first, center.second);
|
setDrawingCenter(center.first, center.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings().get<SvgSectionHeightFromStoreys>().get()) {
|
if (settings().get<SvgSectionHeightFromStoreys>().get() && file) {
|
||||||
if (settings().get<SvgSectionHeight>().has()) {
|
if (settings().get<SvgSectionHeight>().has()) {
|
||||||
setSectionHeightsFromStoreys(settings().get<SvgSectionHeight>().get());
|
setSectionHeightsFromStoreys(settings().get<SvgSectionHeight>().get());
|
||||||
} else {
|
} else {
|
||||||
@@ -181,11 +199,19 @@ void SvgSerializer::apply_settings() {
|
|||||||
setUseNamespace(settings().get<SvgUseNamespace>().get());
|
setUseNamespace(settings().get<SvgUseNamespace>().get());
|
||||||
setUseHlrPoly(settings().get<SvgUseHlrPoly>().get());
|
setUseHlrPoly(settings().get<SvgUseHlrPoly>().get());
|
||||||
setUsePrefiltering(settings().get<SvgUsePrefiltering>().get());
|
setUsePrefiltering(settings().get<SvgUsePrefiltering>().get());
|
||||||
|
setUnifyInputs(settings().get<SvgUnifyInputs>().get());
|
||||||
setSegmentProjection(settings().get<SvgSegmentProjection>().get());
|
setSegmentProjection(settings().get<SvgSegmentProjection>().get());
|
||||||
setPolygonal(settings().get<SvgPolygonal>().get());
|
setPolygonal(settings().get<SvgPolygonal>().get());
|
||||||
setAlwaysProject(settings().get<SvgAlwaysProject>().get());
|
setAlwaysProject(settings().get<SvgAlwaysProject>().get());
|
||||||
setWithoutStoreys(settings().get<SvgWithoutStoreys>().get());
|
setWithoutStoreys(settings().get<SvgWithoutStoreys>().get());
|
||||||
setNoCSS(settings().get<SvgNoCss>().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()) {
|
if (settings().get<SvgDrawStoreyHeights>().has()) {
|
||||||
setDrawStoreyHeights(parse_storey_height_display(settings().get<SvgDrawStoreyHeights>().get()));
|
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) {
|
void SvgSerializer::setFile(ifcopenshell::file* f) {
|
||||||
|
using namespace ifcopenshell::geometry::settings;
|
||||||
|
|
||||||
file = f;
|
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");
|
auto storeys = f->instances_by_type("IfcBuildingStorey");
|
||||||
if (storeys.empty()) {
|
if (storeys.empty()) {
|
||||||
@@ -2449,6 +2486,7 @@ void SvgSerializer::setFile(ifcopenshell::file* f) {
|
|||||||
delete matrix;
|
delete matrix;
|
||||||
#endif
|
#endif
|
||||||
logger::warning("No building storeys encountered, used for reference:", product);
|
logger::warning("No building storeys encountered, used for reference:", product);
|
||||||
|
apply_section_heights_from_storeys();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2459,6 +2497,8 @@ void SvgSerializer::setFile(ifcopenshell::file* f) {
|
|||||||
|
|
||||||
logger::warning("No building storeys encountered, output might be invalid or missing");
|
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) {
|
void SvgSerializer::setSectionHeight(double h, express::Base storey) {
|
||||||
|
|||||||
Reference in New Issue
Block a user