Skip to content

Commit

Permalink
Merge pull request #484 from hannobraun/orient
Browse files Browse the repository at this point in the history
Fix surface orientation errors
  • Loading branch information
hannobraun authored Apr 14, 2022
2 parents 31ba592 + 8774a58 commit 834ceec
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 17 deletions.
32 changes: 21 additions & 11 deletions crates/fj-kernel/src/algorithms/sweep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,11 @@ pub fn sweep_shape(

// Create top faces.
for face_source in source.topology().faces().values() {
let surface_bottom = target.insert(face_source.surface()).unwrap();
let surface_top = target
.insert(surface_bottom.get().transform(&translation))
.unwrap();
let surface = face_source.surface();

let surface_bottom = target.insert(surface.reverse()).unwrap();
let surface_top =
target.insert(surface.transform(&translation)).unwrap();

let exteriors_bottom =
source_to_bottom.exteriors_for_face(&face_source);
Expand Down Expand Up @@ -328,7 +329,8 @@ mod tests {
fn sweep() -> anyhow::Result<()> {
let tolerance = Tolerance::from_scalar(Scalar::ONE).unwrap();

let sketch = Triangle::new([[0., 0., 0.], [1., 0., 0.], [0., 1., 0.]])?;
let sketch =
Triangle::new([[0., 0., 0.], [1., 0., 0.], [0., 1., 0.]], false)?;

let mut swept = sweep_shape(
sketch.shape,
Expand All @@ -337,9 +339,12 @@ mod tests {
[255, 0, 0, 255],
);

let bottom_face = sketch.face.get();
let bottom_face =
Triangle::new([[0., 0., 0.], [1., 0., 0.], [0., 1., 0.]], true)?
.face
.get();
let top_face =
Triangle::new([[0., 0., 1.], [1., 0., 1.], [0., 1., 1.]])?
Triangle::new([[0., 0., 1.], [1., 0., 1.], [0., 1., 1.]], false)?
.face
.get();

Expand Down Expand Up @@ -372,7 +377,10 @@ mod tests {
}

impl Triangle {
fn new(points: [impl Into<Point<3>>; 3]) -> anyhow::Result<Self> {
fn new(
points: [impl Into<Point<3>>; 3],
reverse: bool,
) -> anyhow::Result<Self> {
let mut shape = Shape::new();

let [a, b, c] = points.map(|point| point.into());
Expand All @@ -388,9 +396,11 @@ mod tests {
edges: vec![ab, bc, ca],
})?;

let surface = shape.insert(Surface::SweptCurve(
SweptCurve::plane_from_points([a, b, c]),
))?;
let surface =
Surface::SweptCurve(SweptCurve::plane_from_points([a, b, c]));
let surface = if reverse { surface.reverse() } else { surface };
let surface = shape.insert(surface)?;

let abc = Face::Face {
surface,
exteriors: vec![cycles],
Expand Down
7 changes: 7 additions & 0 deletions crates/fj-kernel/src/geometry/curves/arc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ impl Arc {
self.center
}

/// Create a new instance that is reversed
#[must_use]
pub fn reverse(mut self) -> Self {
self.length = -self.length;
self
}

/// Create a new instance that is transformed by `transform`
#[must_use]
pub fn transform(self, transform: &Transform) -> Self {
Expand Down
7 changes: 7 additions & 0 deletions crates/fj-kernel/src/geometry/curves/line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ impl Line {
self.origin
}

/// Create a new instance that is reversed
#[must_use]
pub fn reverse(mut self) -> Self {
self.direction = -self.direction;
self
}

/// Create a new instance that is transformed by `transform`
#[must_use]
pub fn transform(self, transform: &Transform) -> Self {
Expand Down
9 changes: 9 additions & 0 deletions crates/fj-kernel/src/geometry/curves/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@ impl Curve {
}
}

/// Create a new instance that is reversed
#[must_use]
pub fn reverse(self) -> Self {
match self {
Self::Arc(curve) => Self::Arc(curve.reverse()),
Self::Line(curve) => Self::Line(curve.reverse()),
}
}

/// Create a new instance that is transformed by `transform`
#[must_use]
pub fn transform(self, transform: &Transform) -> Self {
Expand Down
8 changes: 8 additions & 0 deletions crates/fj-kernel/src/geometry/surfaces/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ impl Surface {
})
}

/// Create a new instance that is reversed
#[must_use]
pub fn reverse(self) -> Self {
match self {
Self::SweptCurve(surface) => Self::SweptCurve(surface.reverse()),
}
}

/// Transform the surface
#[must_use]
pub fn transform(self, transform: &Transform) -> Self {
Expand Down
7 changes: 7 additions & 0 deletions crates/fj-kernel/src/geometry/surfaces/swept.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ impl SweptCurve {
Self { curve, path }
}

/// Create a new instance that is reversed
#[must_use]
pub fn reverse(mut self) -> Self {
self.curve = self.curve.reverse();
self
}

/// Transform the surface
#[must_use]
pub fn transform(mut self, transform: &Transform) -> Self {
Expand Down
27 changes: 22 additions & 5 deletions crates/fj-operations/src/difference_2d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,15 @@ impl ToShape for fj::Difference2d {
.map(|shape| shape.topology().cycles().next().unwrap());

let mut vertices = HashMap::new();

let cycle_a = add_cycle(cycle_a, &mut vertices, &mut shape, false);
let cycle_b = add_cycle(cycle_b, &mut vertices, &mut shape, true);

let mut exteriors = Vec::new();
let mut interiors = Vec::new();

exteriors.push(add_cycle(cycle_a, &mut vertices, &mut shape));
interiors.push(add_cycle(cycle_b, &mut vertices, &mut shape));
exteriors.push(cycle_a);
interiors.push(cycle_b);

// Can't panic, as we just verified that both shapes have one face.
let [face_a, face_b] = [&mut a, &mut b]
Expand Down Expand Up @@ -92,26 +96,39 @@ fn add_cycle(
cycle: Handle<Cycle>,
vertices: &mut HashMap<Vertex, Handle<Vertex>>,
shape: &mut Shape,
reverse: bool,
) -> Handle<Cycle> {
let mut edges = Vec::new();
for edge in cycle.get().edges() {
let curve = shape.insert(edge.curve()).unwrap();
let curve = edge.curve();
let curve = if reverse { curve.reverse() } else { curve };
let curve = shape.insert(curve).unwrap();

let vertices = edge.vertices().clone().map(|vs| {
vs.map(|vertex| {
let mut vs = vs.map(|vertex| {
vertices
.entry(vertex.clone())
.or_insert_with(|| {
let point = shape.insert(vertex.point()).unwrap();
shape.insert(Vertex { point }).unwrap()
})
.clone()
})
});

if reverse {
vs.reverse();
}

vs
});

let edge = shape.insert(Edge { curve, vertices }).unwrap();
edges.push(edge);
}

if reverse {
edges.reverse();
}

shape.insert(Cycle { edges }).unwrap()
}
2 changes: 1 addition & 1 deletion crates/fj-viewer/src/graphics/shader.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ let pi: f32 = 3.14159265359;
fn frag_model(in: VertexOutput) -> [[location(0)]] vec4<f32> {
let light = vec3<f32>(0.0, 0.0, -1.0);

let angle = acos(abs(dot(light, -in.normal)));
let angle = acos(dot(light, -in.normal));
let f_angle = angle / (pi / 2.0);

let f_normal = max(1.0 - f_angle, 0.0);
Expand Down

0 comments on commit 834ceec

Please sign in to comment.