mirror of
https://github.com/gumyr/build123d.git
synced 2025-12-06 02:30:55 -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
|
conda install -c cadquery -c conda-forge cadquery=master
|
||||||
pip install svgwrite svgpathtools anytree scipy ipython \
|
pip install svgwrite svgpathtools anytree scipy ipython \
|
||||||
ocp_tessellate webcolors==1.12 numpy numpy-quaternion cachetools==5.2.0 \
|
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
|
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>`_
|
`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",
|
"numpy-stl >= 3.0.0, <4",
|
||||||
"ipython >= 8.0.0, <9",
|
"ipython >= 8.0.0, <9",
|
||||||
"py_lib3mf @ git+https://github.com/jdegenstein/py-lib3mf",
|
"py_lib3mf @ git+https://github.com/jdegenstein/py-lib3mf",
|
||||||
|
"ocpsvg @ git+https://github.com/snoyer/ocpsvg",
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
|
|
|
||||||
|
|
@ -30,35 +30,19 @@ license:
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from math import degrees
|
from math import degrees
|
||||||
from typing import Union
|
from pathlib import Path
|
||||||
from stl.mesh import Mesh
|
from typing import TextIO, Union
|
||||||
from svgpathtools import svg2paths
|
|
||||||
from OCP.TopoDS import TopoDS_Face, TopoDS_Shape
|
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.BRep import BRep_Builder
|
||||||
from OCP.BRepTools import BRepTools
|
from OCP.BRepTools import BRepTools
|
||||||
from OCP.STEPControl import STEPControl_Reader
|
|
||||||
import OCP.IFSelect
|
|
||||||
from OCP.RWStl import RWStl
|
from OCP.RWStl import RWStl
|
||||||
from OCP.BRepBuilderAPI import (
|
from OCP.STEPControl import STEPControl_Reader
|
||||||
BRepBuilderAPI_MakeEdge,
|
from OCP.TopoDS import TopoDS_Face, TopoDS_Shape, TopoDS_Wire
|
||||||
BRepBuilderAPI_MakeFace,
|
from ocpsvg import ColorAndLabel, import_svg_document
|
||||||
BRepBuilderAPI_MakeSolid,
|
from svgpathtools import svg2paths
|
||||||
BRepBuilderAPI_MakeVertex,
|
|
||||||
BRepBuilderAPI_MakeWire,
|
|
||||||
BRepBuilderAPI_Sewing,
|
|
||||||
)
|
|
||||||
from OCP.gp import gp_Pnt
|
|
||||||
|
|
||||||
from build123d.topology import (
|
|
||||||
Compound,
|
|
||||||
Edge,
|
|
||||||
Face,
|
|
||||||
Shape,
|
|
||||||
ShapeList,
|
|
||||||
Shell,
|
|
||||||
Solid,
|
|
||||||
downcast,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def import_brep(file_name: str) -> Shape:
|
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)
|
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
|
"""import_svg
|
||||||
|
|
||||||
Get a ShapeList of Edge from the paths in the provided svg file.
|
|
||||||
|
|
||||||
Args:
|
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:
|
Raises:
|
||||||
ValueError: File not found
|
ValueError: unexpected shape type
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
ShapeList[Edge]: Edges in svg file
|
ShapeList[Union[Wire, Face]]: objects contained in svg
|
||||||
"""
|
"""
|
||||||
if not os.path.exists(file_name):
|
shapes = []
|
||||||
raise ValueError(f"{file_name} not found")
|
label_by = (
|
||||||
svg_code, builder_name = import_svg_as_buildline_code(file_name)
|
"{http://www.inkscape.org/namespaces/inkscape}" + label_by
|
||||||
ex_locals = {}
|
if is_inkscape_label
|
||||||
exec(svg_code, None, ex_locals)
|
else label_by
|
||||||
return ex_locals[builder_name].edges()
|
)
|
||||||
|
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,
|
Bezier,
|
||||||
RadiusArc,
|
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
|
from build123d.exporters import ExportSVG
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -57,25 +57,21 @@ class ImportSVG(unittest.TestCase):
|
||||||
|
|
||||||
self.assertEqual(builder_name, "builder")
|
self.assertEqual(builder_name, "builder")
|
||||||
|
|
||||||
# def test_import_svg_as_buildline_code_ccw(self):
|
def test_import_svg(self):
|
||||||
# # Create svg file
|
for tag in ["id", "label"]:
|
||||||
# with BuildLine() as test_obj:
|
# Import the svg object as a ShapeList
|
||||||
# l3 = RadiusArc((0, 1), (0, 0), 1.5)
|
svg = import_svg(
|
||||||
# show(test_obj)
|
"svg_import_test.svg", label_by=tag, is_inkscape_label=tag == "label"
|
||||||
# svg = ExportSVG()
|
)
|
||||||
# svg.add_shape(test_obj.wires()[0], "")
|
|
||||||
# svg.write("test.svg")
|
|
||||||
|
|
||||||
# # Read the svg as code
|
# Exact the shape of the plate & holes
|
||||||
# buildline_code, builder_name = import_svg_as_buildline_code("test.svg")
|
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
|
self.assertEqual(len(list(base_faces)), 1)
|
||||||
# ex_locals = {}
|
self.assertEqual(len(list(hole_faces)), 2)
|
||||||
# exec(buildline_code, None, ex_locals)
|
self.assertEqual(len(list(test_wires)), 1)
|
||||||
# test_obj: BuildLine = ex_locals[builder_name]
|
|
||||||
# os.remove("test.svg")
|
|
||||||
|
|
||||||
# self.assertEqual(test_obj.edges()[0].geom_type(), "ELLIPSE")
|
|
||||||
|
|
||||||
|
|
||||||
class ImportBREP(unittest.TestCase):
|
class ImportBREP(unittest.TestCase):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue