242 lines
7.2 KiB
Python
242 lines
7.2 KiB
Python
"""Tests for Fluency CAD geometry kernel."""
|
|
|
|
import pytest
|
|
import numpy as np
|
|
|
|
from fluency.geometry_occ.kernel import OCGeometryKernel, OCCGeometryObject
|
|
from fluency.geometry_occ.sketch import OCCSketch
|
|
from fluency.geometry.base import Point2D
|
|
|
|
|
|
class TestOCGeometryKernel:
|
|
"""Tests for the OpenCASCADE geometry kernel."""
|
|
|
|
def test_kernel_creation(self):
|
|
"""Test kernel can be created."""
|
|
kernel = OCGeometryKernel()
|
|
assert kernel is not None
|
|
|
|
def test_create_point(self):
|
|
"""Test point creation."""
|
|
kernel = OCGeometryKernel()
|
|
point = kernel.create_point(10.0, 20.0)
|
|
assert point is not None
|
|
|
|
def test_create_line(self):
|
|
"""Test line creation."""
|
|
kernel = OCGeometryKernel()
|
|
start = Point2D(0, 0)
|
|
end = Point2D(10, 10)
|
|
line = kernel.create_line(start, end)
|
|
assert line is not None
|
|
|
|
def test_create_circle(self):
|
|
"""Test circle creation."""
|
|
kernel = OCGeometryKernel()
|
|
center = Point2D(0, 0)
|
|
circle = kernel.create_circle(center, 5.0)
|
|
assert circle is not None
|
|
|
|
def test_create_rectangle(self):
|
|
"""Test rectangle creation."""
|
|
kernel = OCGeometryKernel()
|
|
rect = kernel.create_rectangle(10.0, 20.0)
|
|
assert rect is not None
|
|
|
|
def test_create_polygon(self):
|
|
"""Test polygon creation."""
|
|
kernel = OCGeometryKernel()
|
|
points = [
|
|
Point2D(0, 0),
|
|
Point2D(10, 0),
|
|
Point2D(10, 10),
|
|
Point2D(0, 10),
|
|
]
|
|
polygon = kernel.create_polygon(points)
|
|
assert polygon is not None
|
|
|
|
def test_extrude_polygon(self):
|
|
"""Test extruding a polygon."""
|
|
kernel = OCGeometryKernel()
|
|
points = [
|
|
Point2D(0, 0),
|
|
Point2D(10, 0),
|
|
Point2D(10, 10),
|
|
Point2D(0, 10),
|
|
]
|
|
polygon = kernel.create_polygon(points)
|
|
extruded = kernel.extrude(polygon, 20.0)
|
|
assert extruded is not None
|
|
|
|
def test_get_mesh(self):
|
|
"""Test mesh generation."""
|
|
kernel = OCGeometryKernel()
|
|
points = [
|
|
Point2D(0, 0),
|
|
Point2D(10, 0),
|
|
Point2D(10, 10),
|
|
Point2D(0, 10),
|
|
]
|
|
polygon = kernel.create_polygon(points)
|
|
extruded = kernel.extrude(polygon, 20.0)
|
|
|
|
vertices, faces = kernel.get_mesh(extruded)
|
|
|
|
assert len(vertices) > 0
|
|
assert len(faces) > 0
|
|
assert vertices.shape[1] == 3
|
|
assert faces.shape[1] == 3
|
|
|
|
def test_get_bounding_box(self):
|
|
"""Test bounding box calculation."""
|
|
kernel = OCGeometryKernel()
|
|
points = [
|
|
Point2D(0, 0),
|
|
Point2D(10, 0),
|
|
Point2D(10, 10),
|
|
Point2D(0, 10),
|
|
]
|
|
polygon = kernel.create_polygon(points)
|
|
extruded = kernel.extrude(polygon, 20.0)
|
|
|
|
min_pt, max_pt = kernel.get_bounding_box(extruded)
|
|
|
|
assert min_pt.x <= max_pt.x
|
|
assert min_pt.y <= max_pt.y
|
|
assert min_pt.z <= max_pt.z
|
|
|
|
def test_get_volume(self):
|
|
"""Test volume calculation."""
|
|
kernel = OCGeometryKernel()
|
|
points = [
|
|
Point2D(0, 0),
|
|
Point2D(10, 0),
|
|
Point2D(10, 10),
|
|
Point2D(0, 10),
|
|
]
|
|
polygon = kernel.create_polygon(points)
|
|
extruded = kernel.extrude(polygon, 20.0)
|
|
|
|
volume = kernel.get_volume(extruded)
|
|
|
|
assert volume > 0
|
|
assert abs(volume - 2000.0) < 0.1
|
|
|
|
|
|
class TestOCCSketch:
|
|
"""Tests for the OpenCASCADE sketch."""
|
|
|
|
def test_sketch_creation(self):
|
|
"""Test sketch can be created."""
|
|
sketch = OCCSketch()
|
|
assert sketch is not None
|
|
|
|
def test_add_point(self):
|
|
"""Test adding a point."""
|
|
sketch = OCCSketch()
|
|
point = sketch.add_point(10.0, 20.0)
|
|
assert point is not None
|
|
assert point.entity_type == "point"
|
|
|
|
def test_add_line(self):
|
|
"""Test adding a line."""
|
|
sketch = OCCSketch()
|
|
p1 = sketch.add_point(0, 0)
|
|
p2 = sketch.add_point(10, 10)
|
|
line = sketch.add_line(p1, p2)
|
|
assert line is not None
|
|
assert line.entity_type == "line"
|
|
|
|
def test_add_circle(self):
|
|
"""Test adding a circle."""
|
|
sketch = OCCSketch()
|
|
center = sketch.add_point(0, 0)
|
|
circle = sketch.add_circle(center, 5.0)
|
|
assert circle is not None
|
|
assert circle.entity_type == "circle"
|
|
|
|
def test_add_rectangle(self):
|
|
"""Test adding a rectangle."""
|
|
sketch = OCCSketch()
|
|
entities = sketch.add_rectangle((0, 0), (10, 10))
|
|
assert len(entities) == 8
|
|
|
|
def test_get_points(self):
|
|
"""Test getting points."""
|
|
sketch = OCCSketch()
|
|
sketch.add_point(0, 0)
|
|
sketch.add_point(10, 10)
|
|
sketch.add_point(20, 20)
|
|
|
|
points = sketch.get_points()
|
|
assert len(points) == 3
|
|
|
|
def test_clear(self):
|
|
"""Test clearing sketch."""
|
|
sketch = OCCSketch()
|
|
sketch.add_point(0, 0)
|
|
sketch.add_point(10, 10)
|
|
|
|
sketch.clear()
|
|
|
|
points = sketch.get_points()
|
|
assert len(points) == 0
|
|
|
|
def test_workplane_extrude_along_normal(self):
|
|
"""A sketch on a tilted plane extrudes along that plane's normal."""
|
|
import math
|
|
from OCP.GProp import GProp_GProps
|
|
from OCP.BRepGProp import BRepGProp
|
|
|
|
ang = math.radians(35)
|
|
normal = (math.sin(ang), 0.0, math.cos(ang))
|
|
x_dir = (math.cos(ang), 0.0, -math.sin(ang))
|
|
|
|
sk = OCCSketch()
|
|
sk.set_workplane((10.0, 0.0, 5.0), normal, x_dir)
|
|
# 20x20 square in UV
|
|
p0 = sk.add_point(-10, -10); p1 = sk.add_point(10, -10)
|
|
p2 = sk.add_point(10, 10); p3 = sk.add_point(-10, 10)
|
|
sk.add_line(p0, p1); sk.add_line(p1, p2)
|
|
sk.add_line(p2, p3); sk.add_line(p3, p0)
|
|
|
|
geom = sk.get_geometry()
|
|
# The face must carry the plane normal for the kernel.
|
|
assert geom.metadata.get("normal") is not None
|
|
|
|
kernel = OCGeometryKernel()
|
|
solid = kernel.extrude(geom, 15.0)
|
|
s = kernel._get_shape(solid)
|
|
g = GProp_GProps()
|
|
BRepGProp.VolumeProperties_s(s, g)
|
|
# 20 * 20 * 15 = 6000 regardless of plane orientation.
|
|
assert abs(g.Mass() - 6000.0) < 0.1
|
|
|
|
def test_workplane_extrude_with_hole(self):
|
|
"""A square with a circular hole on a custom plane extrudes correctly."""
|
|
import math
|
|
from OCP.GProp import GProp_GProps
|
|
from OCP.BRepGProp import BRepGProp
|
|
|
|
sk = OCCSketch()
|
|
sk.set_workplane((0, 0, 0), (0, 0, 1), (1, 0, 0))
|
|
a = sk.add_point(-10, -10); b = sk.add_point(10, -10)
|
|
c = sk.add_point(10, 10); d = sk.add_point(-10, 10)
|
|
sk.add_line(a, b); sk.add_line(b, c)
|
|
sk.add_line(c, d); sk.add_line(d, a)
|
|
ctr = sk.add_point(0, 0)
|
|
sk.add_circle(ctr, 3.0)
|
|
|
|
geom = sk.get_geometry()
|
|
kernel = OCGeometryKernel()
|
|
solid = kernel.extrude(geom, 5.0)
|
|
s = kernel._get_shape(solid)
|
|
g = GProp_GProps()
|
|
BRepGProp.VolumeProperties_s(s, g)
|
|
expected = 20 * 20 * 5 - math.pi * 3 * 3 * 5
|
|
assert abs(g.Mass() - expected) < 0.1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
pytest.main([__file__, "-v"])
|