mirror of
https://github.com/gumyr/build123d.git
synced 2025-12-05 18:20:46 -08:00
Changing import_svg to use ocpsvg
This commit is contained in:
parent
8baf47549b
commit
dd4f923f6c
5 changed files with 149 additions and 57 deletions
|
|
@ -108,7 +108,8 @@ A procedure for avoiding this issue is to install in a conda environment, which
|
|||
conda install -c cadquery -c conda-forge cadquery=master
|
||||
pip install svgwrite svgpathtools anytree scipy ipython \
|
||||
ocp_tessellate webcolors==1.12 numpy numpy-quaternion cachetools==5.2.0 \
|
||||
ocp_vscode requests orjson urllib3 certifi numpy-stl git+https://github.com/jdegenstein/py-lib3mf
|
||||
ocp_vscode requests orjson urllib3 certifi numpy-stl git+https://github.com/jdegenstein/py-lib3mf \
|
||||
git+https://github.com/snoyer/ocpsvg
|
||||
pip install --no-deps git+https://github.com/gumyr/build123d
|
||||
|
||||
`You can track the issue here <https://github.com/CadQuery/ocp-build-system/issues/11#issuecomment-1407769681>`_
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ dependencies = [
|
|||
"numpy-stl >= 3.0.0, <4",
|
||||
"ipython >= 8.0.0, <9",
|
||||
"py_lib3mf @ git+https://github.com/jdegenstein/py-lib3mf",
|
||||
"ocpsvg @ git+https://github.com/snoyer/ocpsvg",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
|
|
|
|||
|
|
@ -30,35 +30,19 @@ license:
|
|||
|
||||
import os
|
||||
from math import degrees
|
||||
from typing import Union
|
||||
from stl.mesh import Mesh
|
||||
from svgpathtools import svg2paths
|
||||
from OCP.TopoDS import TopoDS_Face, TopoDS_Shape
|
||||
from pathlib import Path
|
||||
from typing import TextIO, Union
|
||||
|
||||
import OCP.IFSelect
|
||||
from build123d.geometry import Color
|
||||
from build123d.topology import Compound, Face, Shape, ShapeList, Wire
|
||||
from OCP.BRep import BRep_Builder
|
||||
from OCP.BRepTools import BRepTools
|
||||
from OCP.STEPControl import STEPControl_Reader
|
||||
import OCP.IFSelect
|
||||
from OCP.RWStl import RWStl
|
||||
from OCP.BRepBuilderAPI import (
|
||||
BRepBuilderAPI_MakeEdge,
|
||||
BRepBuilderAPI_MakeFace,
|
||||
BRepBuilderAPI_MakeSolid,
|
||||
BRepBuilderAPI_MakeVertex,
|
||||
BRepBuilderAPI_MakeWire,
|
||||
BRepBuilderAPI_Sewing,
|
||||
)
|
||||
from OCP.gp import gp_Pnt
|
||||
|
||||
from build123d.topology import (
|
||||
Compound,
|
||||
Edge,
|
||||
Face,
|
||||
Shape,
|
||||
ShapeList,
|
||||
Shell,
|
||||
Solid,
|
||||
downcast,
|
||||
)
|
||||
from OCP.STEPControl import STEPControl_Reader
|
||||
from OCP.TopoDS import TopoDS_Face, TopoDS_Shape, TopoDS_Wire
|
||||
from ocpsvg import ColorAndLabel, import_svg_document
|
||||
from svgpathtools import svg2paths
|
||||
|
||||
|
||||
def import_brep(file_name: str) -> Shape:
|
||||
|
|
@ -219,23 +203,49 @@ def import_svg_as_buildline_code(file_name: str) -> tuple[str, str]:
|
|||
return ("\n".join(buildline_code), builder_name)
|
||||
|
||||
|
||||
def import_svg(file_name: str) -> ShapeList[Edge]:
|
||||
def import_svg(
|
||||
svg_file: Union[str, Path, TextIO],
|
||||
*,
|
||||
flip_y: bool = True,
|
||||
ignore_visibility: bool = False,
|
||||
label_by: str = "id",
|
||||
is_inkscape_label: bool = False,
|
||||
) -> ShapeList[Union[Wire, Face]]:
|
||||
"""import_svg
|
||||
|
||||
Get a ShapeList of Edge from the paths in the provided svg file.
|
||||
|
||||
Args:
|
||||
filepath (str): svg file
|
||||
svg_file (Union[str, Path, TextIO]): svg file
|
||||
flip_y (bool, optional): flip objects to compensate for svg orientation. Defaults to True.
|
||||
ignore_visibility (bool, optional): Defaults to False.
|
||||
label_by (str, optional): xml attribute. Defaults to "id".
|
||||
|
||||
Raises:
|
||||
ValueError: File not found
|
||||
ValueError: unexpected shape type
|
||||
|
||||
Returns:
|
||||
ShapeList[Edge]: Edges in svg file
|
||||
ShapeList[Union[Wire, Face]]: objects contained in svg
|
||||
"""
|
||||
if not os.path.exists(file_name):
|
||||
raise ValueError(f"{file_name} not found")
|
||||
svg_code, builder_name = import_svg_as_buildline_code(file_name)
|
||||
ex_locals = {}
|
||||
exec(svg_code, None, ex_locals)
|
||||
return ex_locals[builder_name].edges()
|
||||
shapes = []
|
||||
label_by = (
|
||||
"{http://www.inkscape.org/namespaces/inkscape}" + label_by
|
||||
if is_inkscape_label
|
||||
else label_by
|
||||
)
|
||||
for face_or_wire, color_and_label in import_svg_document(
|
||||
svg_file,
|
||||
flip_y=flip_y,
|
||||
ignore_visibility=ignore_visibility,
|
||||
metadata=ColorAndLabel.Label_by(label_by),
|
||||
):
|
||||
if isinstance(face_or_wire, TopoDS_Wire):
|
||||
shape = Wire(face_or_wire)
|
||||
elif isinstance(face_or_wire, TopoDS_Face):
|
||||
shape = Face(face_or_wire)
|
||||
else: # should not happen
|
||||
raise ValueError(f"unexpected shape type: {type(face_or_wire).__name__}")
|
||||
|
||||
shape.color = Color(*color_and_label.color)
|
||||
shape.label = color_and_label.label
|
||||
shapes.append(shape)
|
||||
|
||||
return ShapeList(shapes)
|
||||
|
|
|
|||
84
tests/svg_import_test.svg
Normal file
84
tests/svg_import_test.svg
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="210mm"
|
||||
height="297mm"
|
||||
viewBox="0 0 210 297"
|
||||
version="1.1"
|
||||
id="svg933"
|
||||
inkscape:version="1.2.2 (732a01da63, 2022-12-09, custom)"
|
||||
sodipodi:docname="svg_import_test.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview935"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.414741"
|
||||
inkscape:cx="224.4227"
|
||||
inkscape:cy="583.49903"
|
||||
inkscape:window-width="2490"
|
||||
inkscape:window-height="1536"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer4" />
|
||||
<defs
|
||||
id="defs930" />
|
||||
<g
|
||||
inkscape:label="Base"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<path
|
||||
id="id_base"
|
||||
style="display:inline;stroke-width:0.264583"
|
||||
d="m 45.732092,105.28401 a 10.107891,10.107891 0 0 0 -10.10791,10.10791 v 58.42021 a 10.107891,10.107891 0 0 0 10.10791,10.10791 h 68.861948 a 10.107891,10.107891 0 0 0 10.10791,-10.10791 v -58.42021 a 10.107891,10.107891 0 0 0 -10.10791,-10.10791 z"
|
||||
inkscape:label="label_base" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer4"
|
||||
inkscape:label="Wire">
|
||||
<path
|
||||
style="fill:none;stroke-width:0.264583;stroke:#000000;stroke-opacity:1"
|
||||
d="M 54.771808,98.981222 H 123.4902 v 0"
|
||||
id="id_wire"
|
||||
inkscape:label="label_wire" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="Hole1">
|
||||
<circle
|
||||
style="fill:#800000;stroke-width:0.264583"
|
||||
id="id_red_hole"
|
||||
cx="54.771809"
|
||||
cy="126.52283"
|
||||
r="11.419678"
|
||||
inkscape:label="label_red_hole"
|
||||
inkscape:highlight-color="#ee3b45" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer3"
|
||||
inkscape:label="Hole2">
|
||||
<circle
|
||||
style="fill:#000080;stroke-width:0.264583"
|
||||
id="id_blue_hole"
|
||||
cx="98.322319"
|
||||
cy="160.14645"
|
||||
r="18.159254"
|
||||
inkscape:label="label_blue_hole"
|
||||
inkscape:highlight-color="#3e62e3" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
|
|
@ -6,7 +6,7 @@ from build123d import (
|
|||
Bezier,
|
||||
RadiusArc,
|
||||
)
|
||||
from build123d.importers import import_svg_as_buildline_code, import_brep
|
||||
from build123d.importers import import_svg_as_buildline_code, import_brep, import_svg
|
||||
from build123d.exporters import ExportSVG
|
||||
|
||||
|
||||
|
|
@ -57,25 +57,21 @@ class ImportSVG(unittest.TestCase):
|
|||
|
||||
self.assertEqual(builder_name, "builder")
|
||||
|
||||
# def test_import_svg_as_buildline_code_ccw(self):
|
||||
# # Create svg file
|
||||
# with BuildLine() as test_obj:
|
||||
# l3 = RadiusArc((0, 1), (0, 0), 1.5)
|
||||
# show(test_obj)
|
||||
# svg = ExportSVG()
|
||||
# svg.add_shape(test_obj.wires()[0], "")
|
||||
# svg.write("test.svg")
|
||||
def test_import_svg(self):
|
||||
for tag in ["id", "label"]:
|
||||
# Import the svg object as a ShapeList
|
||||
svg = import_svg(
|
||||
"svg_import_test.svg", label_by=tag, is_inkscape_label=tag == "label"
|
||||
)
|
||||
|
||||
# # Read the svg as code
|
||||
# buildline_code, builder_name = import_svg_as_buildline_code("test.svg")
|
||||
# Exact the shape of the plate & holes
|
||||
base_faces = svg.filter_by(lambda f: "base" in f.label)
|
||||
hole_faces = svg.filter_by(lambda f: "hole" in f.label)
|
||||
test_wires = svg.filter_by(lambda f: "wire" in f.label)
|
||||
|
||||
# # Execute it and convert to Edges
|
||||
# ex_locals = {}
|
||||
# exec(buildline_code, None, ex_locals)
|
||||
# test_obj: BuildLine = ex_locals[builder_name]
|
||||
# os.remove("test.svg")
|
||||
|
||||
# self.assertEqual(test_obj.edges()[0].geom_type(), "ELLIPSE")
|
||||
self.assertEqual(len(list(base_faces)), 1)
|
||||
self.assertEqual(len(list(hole_faces)), 2)
|
||||
self.assertEqual(len(list(test_wires)), 1)
|
||||
|
||||
|
||||
class ImportBREP(unittest.TestCase):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue