- Added save file foramt

- Split main.py refactor
This commit is contained in:
bklronin
2026-07-07 21:51:27 +02:00
parent 5269c0897c
commit 80ba3cc70a
3 changed files with 74 additions and 63 deletions
+14 -3
View File
@@ -4,8 +4,10 @@
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="8f0bafd6-58a0-4b20-aa2b-ddc3ba278873" name="Changes" comment="- assembly draft">
<list default="true" id="8f0bafd6-58a0-4b20-aa2b-ddc3ba278873" name="Changes" comment="- Added save file foramt&#10;- Split main.py refactor">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/fluency/ui/main_window.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/fluency/ui/main_window.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/fluency/ui/sketch_widget.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/fluency/ui/sketch_widget.py" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -334,7 +336,15 @@
<option name="project" value="LOCAL" />
<updated>1783272988957</updated>
</task>
<option name="localTasksCounter" value="29" />
<task id="LOCAL-00029" summary="- Added save file foramt&#10;- Split main.py refactor">
<option name="closed" value="true" />
<created>1783282570014</created>
<option name="number" value="00029" />
<option name="presentableId" value="LOCAL-00029" />
<option name="project" value="LOCAL" />
<updated>1783282570014</updated>
</task>
<option name="localTasksCounter" value="30" />
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
@@ -378,6 +388,7 @@
<MESSAGE value="- sketch enhacements" />
<MESSAGE value="- UI refinement, button position ui file as source no dirty drafting anymore" />
<MESSAGE value="- assembly draft" />
<option name="LAST_COMMIT_MESSAGE" value="- assembly draft" />
<MESSAGE value="- Added save file foramt&#10;- Split main.py refactor" />
<option name="LAST_COMMIT_MESSAGE" value="- Added save file foramt&#10;- Split main.py refactor" />
</component>
</project>
-60
View File
@@ -80,66 +80,6 @@ from gui_ui import Ui_fluencyCAD # auto-generated Qt form (project root on sys.
logger = logging.getLogger(__name__)
def _project_face_to_uv(
face: Any,
workplane: Tuple[Tuple[float, float, float], Tuple[float, float, float], Tuple[float, float, float]],
) -> List[List[Tuple[float, float]]]:
"""Project a planar ``TopoDS_Face``'s boundary edges into the UV frame.
*workplane* is (origin, normal, x_dir). Returns a list of polylines,
each a list of (u, v) points, one per boundary edge (lines → endpoints,
curves → sampled). Used by the 2D sketch widget to draw the face as an
underlay when sketching on a surface.
"""
import numpy as np
from OCP.TopExp import TopExp_Explorer
from OCP.TopAbs import TopAbs_EDGE, TopAbs_WIRE
from OCP.TopoDS import TopoDS
from OCP.BRepAdaptor import BRepAdaptor_Curve
from OCP.GeomAbs import GeomAbs_Line
from OCP.gp import gp_Pnt
origin = np.asarray(workplane[0], dtype=float) # (x,y,z)
normal = np.asarray(workplane[1], dtype=float) # plane normal
x_dir = np.asarray(workplane[2], dtype=float) # in-plane x axis
x_dir = x_dir / np.linalg.norm(x_dir)
normal = normal / np.linalg.norm(normal)
y_dir = np.cross(normal, x_dir)
y_dir = y_dir / np.linalg.norm(y_dir)
def world_to_uv(p: gp_Pnt) -> Tuple[float, float]:
v = np.array([p.X() - origin[0], p.Y() - origin[1], p.Z() - origin[2]])
return (float(np.dot(v, x_dir)), float(np.dot(v, y_dir)))
polylines: List[List[Tuple[float, float]]] = []
# Iterate wires of the face (outer + inner = holes), then edges.
wire_expl = TopExp_Explorer(face, TopAbs_WIRE)
while wire_expl.More():
wire = wire_expl.Current()
edge_expl = TopExp_Explorer(wire, TopAbs_EDGE)
while edge_expl.More():
edge = TopoDS.Edge_s(edge_expl.Current())
try:
crv = BRepAdaptor_Curve(edge)
f = crv.FirstParameter()
l = crv.LastParameter()
is_line = crv.GetType() == GeomAbs_Line
if is_line:
pts = [crv.Value(f), crv.Value(l)]
else:
# Sample 32 segments across the parameter range.
pts = [crv.Value(f + (l - f) * i / 32.0) for i in range(33)]
poly = [world_to_uv(p) for p in pts]
polylines.append(poly)
except Exception:
pass
edge_expl.Next()
wire_expl.Next()
return polylines
def _project_body_to_workplane(
body_shape: Any,
workplane: Tuple[Tuple[float, float, float], Tuple[float, float, float], Tuple[float, float, float]],
+60
View File
@@ -28,6 +28,66 @@ from fluency.geometry_occ.sketch import OCCSketch, OCCSketchEntity
logger = logging.getLogger(__name__)
def _project_face_to_uv(
face: Any,
workplane: Tuple[Tuple[float, float, float], Tuple[float, float, float], Tuple[float, float, float]],
) -> List[List[Tuple[float, float]]]:
"""Project a planar ``TopoDS_Face``'s boundary edges into the UV frame.
*workplane* is (origin, normal, x_dir). Returns a list of polylines,
each a list of (u, v) points, one per boundary edge (lines \u2192 endpoints,
curves \u2192 sampled). Used by the 2D sketch widget to draw the face as an
underlay when sketching on a surface.
"""
import numpy as np
from OCP.TopExp import TopExp_Explorer
from OCP.TopAbs import TopAbs_EDGE, TopAbs_WIRE
from OCP.TopoDS import TopoDS
from OCP.BRepAdaptor import BRepAdaptor_Curve
from OCP.GeomAbs import GeomAbs_Line
from OCP.gp import gp_Pnt
origin = np.asarray(workplane[0], dtype=float) # (x,y,z)
normal = np.asarray(workplane[1], dtype=float) # plane normal
x_dir = np.asarray(workplane[2], dtype=float) # in-plane x axis
x_dir = x_dir / np.linalg.norm(x_dir)
normal = normal / np.linalg.norm(normal)
y_dir = np.cross(normal, x_dir)
y_dir = y_dir / np.linalg.norm(y_dir)
def world_to_uv(p: gp_Pnt) -> Tuple[float, float]:
v = np.array([p.X() - origin[0], p.Y() - origin[1], p.Z() - origin[2]])
return (float(np.dot(v, x_dir)), float(np.dot(v, y_dir)))
polylines: List[List[Tuple[float, float]]] = []
# Iterate wires of the face (outer + inner = holes), then edges.
wire_expl = TopExp_Explorer(face, TopAbs_WIRE)
while wire_expl.More():
wire = wire_expl.Current()
edge_expl = TopExp_Explorer(wire, TopAbs_EDGE)
while edge_expl.More():
edge = TopoDS.Edge_s(edge_expl.Current())
try:
crv = BRepAdaptor_Curve(edge)
f = crv.FirstParameter()
l = crv.LastParameter()
is_line = crv.GetType() == GeomAbs_Line
if is_line:
pts = [crv.Value(f), crv.Value(l)]
else:
# Sample 32 segments across the parameter range.
pts = [crv.Value(f + (l - f) * i / 32.0) for i in range(33)]
poly = [world_to_uv(p) for p in pts]
polylines.append(poly)
except Exception:
pass
edge_expl.Next()
wire_expl.Next()
return polylines
class Sketch2DWidget(QWidget):
"""2D sketching widget with SolveSpace constraint solving and drawing tools."""