mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 23:36:20 +00:00
Fix #4107. Bug where shapely used incorrect raycast coordinates causing fills to not show.
This has been around for 2 years, either it was never noticed or something changed?
This commit is contained in:
@@ -889,15 +889,6 @@ class CreateDrawing(bpy.types.Operator):
|
|||||||
if self.camera.data.BIMCameraProperties.fill_mode == "SHAPELY":
|
if self.camera.data.BIMCameraProperties.fill_mode == "SHAPELY":
|
||||||
# shapely variant
|
# shapely variant
|
||||||
group = root.find("{http://www.w3.org/2000/svg}g")
|
group = root.find("{http://www.w3.org/2000/svg}g")
|
||||||
nm = group.attrib["{http://www.ifcopenshell.org/ns}name"]
|
|
||||||
m4 = np.array(json.loads(group.attrib["{http://www.ifcopenshell.org/ns}plane"]))
|
|
||||||
m3 = np.array(json.loads(group.attrib["{http://www.ifcopenshell.org/ns}matrix3"]))
|
|
||||||
m44 = np.eye(4)
|
|
||||||
m44[0][0:2] = m3[0][0:2]
|
|
||||||
m44[1][0:2] = m3[1][0:2]
|
|
||||||
m44[0][3] = m3[0][2]
|
|
||||||
m44[1][3] = m3[1][2]
|
|
||||||
m44 = np.linalg.inv(m44)
|
|
||||||
|
|
||||||
elements_with_faces = set()
|
elements_with_faces = set()
|
||||||
for element in drawing_elements.copy():
|
for element in drawing_elements.copy():
|
||||||
@@ -930,21 +921,18 @@ class CreateDrawing(bpy.types.Operator):
|
|||||||
if polygon.area < 1:
|
if polygon.area < 1:
|
||||||
continue
|
continue
|
||||||
centroid = polygon.centroid
|
centroid = polygon.centroid
|
||||||
internal_point = centroid if polygon.contains(centroid) else polygon.representative_point()
|
centroid = centroid if polygon.contains(centroid) else polygon.representative_point()
|
||||||
if internal_point:
|
if centroid:
|
||||||
internal_point = [internal_point.x, internal_point.y]
|
centroid3d = self.drawing_to_model_co(centroid.x, centroid.y)
|
||||||
a, b = self.drawing_to_model_co(m44, m4, internal_point, 0.0), self.drawing_to_model_co(
|
inside_elements = [
|
||||||
m44, m4, internal_point, -100.0
|
e for e in tree.select(self.pythonize(centroid3d)) if not e.is_a("IfcAnnotation")
|
||||||
)
|
]
|
||||||
inside_elements = [e for e in tree.select(self.pythonize(a)) if not e.is_a("IfcAnnotation")]
|
|
||||||
if not inside_elements:
|
if not inside_elements:
|
||||||
|
camera_dir = self.camera.matrix_world.col[2].to_3d() * -1
|
||||||
elements = [
|
elements = [
|
||||||
e
|
e
|
||||||
for e in tree.select_ray(self.pythonize(a), self.pythonize(b - a))
|
for e in tree.select_ray(self.pythonize(centroid3d), self.pythonize(camera_dir))
|
||||||
if not e.instance.is_a("IfcAnnotation")
|
if not e.instance.is_a("IfcAnnotation")
|
||||||
and tool.Cad.is_point_on_edge(
|
|
||||||
Vector(list(e.position)), (Vector(self.pythonize(a)), Vector(self.pythonize(b)))
|
|
||||||
)
|
|
||||||
]
|
]
|
||||||
if elements:
|
if elements:
|
||||||
path = etree.Element("path")
|
path = etree.Element("path")
|
||||||
@@ -961,12 +949,6 @@ class CreateDrawing(bpy.types.Operator):
|
|||||||
)
|
)
|
||||||
path.attrib["d"] = d
|
path.attrib["d"] = d
|
||||||
classes = self.get_svg_classes(ifc.by_id(elements[0].instance.id()))
|
classes = self.get_svg_classes(ifc.by_id(elements[0].instance.id()))
|
||||||
classes.append(f"intpoint-{internal_point}")
|
|
||||||
classes.append(f"ab-{a}, {b}")
|
|
||||||
for i, ray_result in enumerate(elements):
|
|
||||||
classes.append(f"el{i}-{ray_result.instance.id()}")
|
|
||||||
classes.append(f"el{i}-pos-{list(ray_result.position)}")
|
|
||||||
classes.append(f"el{i}-dst-{ray_result.distance}")
|
|
||||||
classes.append("surface")
|
classes.append("surface")
|
||||||
path.set("class", " ".join(list(classes)))
|
path.set("class", " ".join(list(classes)))
|
||||||
group.insert(0, path)
|
group.insert(0, path)
|
||||||
@@ -1026,18 +1008,6 @@ class CreateDrawing(bpy.types.Operator):
|
|||||||
|
|
||||||
g2 = list(yield_groups(svg2))[0]
|
g2 = list(yield_groups(svg2))[0]
|
||||||
|
|
||||||
# These are attributes on the original group that we can use to reconstruct
|
|
||||||
# a 4x4 matrix of the projection used in the SVG generation process
|
|
||||||
nm = g1.getAttribute("ifc:name")
|
|
||||||
m4 = np.array(json.loads(g1.getAttribute("ifc:plane")))
|
|
||||||
m3 = np.array(json.loads(g1.getAttribute("ifc:matrix3")))
|
|
||||||
m44 = np.eye(4)
|
|
||||||
m44[0][0:2] = m3[0][0:2]
|
|
||||||
m44[1][0:2] = m3[1][0:2]
|
|
||||||
m44[0][3] = m3[0][2]
|
|
||||||
m44[1][3] = m3[1][2]
|
|
||||||
m44 = np.linalg.inv(m44)
|
|
||||||
|
|
||||||
# Loop over the cell paths
|
# Loop over the cell paths
|
||||||
for pi, p in enumerate(g2.getElementsByTagName("path")):
|
for pi, p in enumerate(g2.getElementsByTagName("path")):
|
||||||
d = p.getAttribute("d")
|
d = p.getAttribute("d")
|
||||||
@@ -1054,30 +1024,34 @@ class CreateDrawing(bpy.types.Operator):
|
|||||||
|
|
||||||
xy = list(map(float, p.getAttribute("ifc:pointInside").split(",")))
|
xy = list(map(float, p.getAttribute("ifc:pointInside").split(",")))
|
||||||
|
|
||||||
a, b = self.drawing_to_model_co(m44, m4, xy, 0.0), self.drawing_to_model_co(m44, m4, xy, -100.0)
|
centroid3d = self.drawing_to_model_co(*xy)
|
||||||
|
|
||||||
inside_elements = [e for e in tree.select(self.pythonize(a)) if not e.is_a("IfcAnnotation")]
|
inside_elements = [
|
||||||
|
e for e in tree.select(self.pythonize(centroid3d)) if not e.is_a("IfcAnnotation")
|
||||||
|
]
|
||||||
if inside_elements:
|
if inside_elements:
|
||||||
elements = None
|
elements = None
|
||||||
if iteration != num_passes:
|
if iteration != num_passes:
|
||||||
semantics[pi] = (inside_elements[0], -1)
|
semantics[pi] = (inside_elements[0], -1)
|
||||||
else:
|
else:
|
||||||
|
camera_dir = self.camera.matrix_world.col[2].to_3d() * -1
|
||||||
elements = [
|
elements = [
|
||||||
e
|
e
|
||||||
for e in tree.select_ray(self.pythonize(a), self.pythonize(b - a))
|
for e in tree.select_ray(self.pythonize(centroid3d), self.pythonize(camera_dir))
|
||||||
if not e.instance.is_a("IfcAnnotation")
|
if not e.instance.is_a("IfcAnnotation")
|
||||||
]
|
]
|
||||||
|
|
||||||
if elements:
|
if elements:
|
||||||
classes = self.get_svg_classes(ifc.by_id(elements[0].instance.id()))
|
classes = self.get_svg_classes(ifc.by_id(elements[0].instance.id()))
|
||||||
classes.append("projection")
|
classes.append("projection")
|
||||||
|
classes.append("surface")
|
||||||
|
|
||||||
if iteration != num_passes:
|
if iteration != num_passes:
|
||||||
semantics[pi] = elements[0]
|
semantics[pi] = elements[0]
|
||||||
else:
|
else:
|
||||||
classes = ["projection"]
|
classes = ["projection"]
|
||||||
|
|
||||||
p.setAttribute("style", "")
|
p.setAttribute("style", "foo")
|
||||||
p.setAttribute("class", " ".join(classes))
|
p.setAttribute("class", " ".join(classes))
|
||||||
|
|
||||||
if iteration != num_passes:
|
if iteration != num_passes:
|
||||||
@@ -1414,7 +1388,6 @@ class CreateDrawing(bpy.types.Operator):
|
|||||||
if layer:
|
if layer:
|
||||||
for query in join_criteria:
|
for query in join_criteria:
|
||||||
key = ifcopenshell.util.selector.get_element_value(layer, query)
|
key = ifcopenshell.util.selector.get_element_value(layer, query)
|
||||||
print("got layer key", query, key)
|
|
||||||
if isinstance(key, (list, tuple)):
|
if isinstance(key, (list, tuple)):
|
||||||
keys.extend(key)
|
keys.extend(key)
|
||||||
else:
|
else:
|
||||||
@@ -1469,10 +1442,11 @@ class CreateDrawing(bpy.types.Operator):
|
|||||||
g.set("class", " ".join(list(classes)))
|
g.set("class", " ".join(list(classes)))
|
||||||
group.append(g)
|
group.append(g)
|
||||||
|
|
||||||
def drawing_to_model_co(self, m44, m4, xy, z=0.0):
|
def drawing_to_model_co(self, x, y):
|
||||||
xyzw = m44 @ np.array(xy + [z, 1.0])
|
camera_xy = np.array((x, -y)) / self.scale / 1000
|
||||||
xyzw[1] *= -1.0
|
camera_props = self.camera.data.BIMCameraProperties
|
||||||
return (m4 @ xyzw)[0:3]
|
camera_xy += np.array((camera_props.width / -2, camera_props.height / 2)) # top left offset
|
||||||
|
return self.camera.matrix_world @ Vector(camera_xy).to_3d()
|
||||||
|
|
||||||
def pythonize(self, arr):
|
def pythonize(self, arr):
|
||||||
return tuple(map(float, arr))
|
return tuple(map(float, arr))
|
||||||
|
|||||||
Reference in New Issue
Block a user