-
Notifications
You must be signed in to change notification settings < 8000 /li> - Fork 64
Shapeops OR function not behaving as expected when solids touch but do not overlap #57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Maybe I'm misunderstanding the purpose of the |
I tried to debug the boolean operations with coplanar faces on https://github.com/tsukimizake/truck/tree/fix-coplanar-boolean-operations-2 . Now I gave up fixing it, but at least I could make or operation of adjacent cubes work. I can use english to some extent, but as the author of this project seems to be also Japanese, I 8000 would like to write it in Japanese. If there is anybody interested, please use a llm to translate it. 最も単純なテストケースとして以下のようなz=1で接し、xy軸をずらすことで他の面は同一平面上にない2つのboxのorで実験しました。 #[test]
fn adjacent_cubes_or() {
let v = builder::vertex(Point3::origin());
let e = builder::tsweep(&v, Vector3::unit_x());
let f = builder::tsweep(&e, Vector3::unit_y());
let cube: Solid = builder::tsweep(&f, Vector3::unit_z());
let v = builder::vertex(Point3::new(0.5, 0.5, 1.0));
let w = builder::tsweep(&v, Vector3::unit_x());
let f = builder::tsweep(&w, Vector3::unit_y());
let cube2: Solid = builder::tsweep(&f, Vector3::unit_z());
let result = crate::or(&cube, &cube2, 0.05);
match &result {
Some(_) => eprintln!("Result is Some"),
None => eprintln!("Result is None"),
}
assert!(
result.is_some(),
"Boolean OR of adjacent cubes should succeed"
);
} これを実行したときまず失敗していたのはdivide_facesの let op = pre_faces.iter_mut().find(|face| face[0].poly.include(pt))?; がNoneを返すというものでした。 この原因はcreate_loops_storeにおいて上のケースでのz=1のような共有面の隣で、相手Shellの辺が交線と見なされてLoopsStoreに追加されてしまうというものでした。
ただ、この対処は全く完全ではなく、例えばcoplanar_faces_or testでは以下のようなLoopsStoreが発生してwire is not simpleとなります。 LoopsStore[4]:
Loop[0] with status: Or
Edges in loop:
Edge: (0, 0.5, 0) -> (0, 0.5, 1)
Edge: (0, 0.5, 1) -> (0, 0, 1)
Edge: (0, 0, 1) -> (0, 0, 0)
Edge: (0, 0, 0) -> (0, 0.5, 0)
Edge: (0, 0.5, 0) -> (0, 1, 0)
Edge: (0, 1, 0) -> (0, 1, 1)
Edge: (0, 1, 1) -> (0, 0.5, 1)
Edge: (0, 0.5, 1) -> (0, 0.5, 0)
Edge: (0, 0.5, 0) -> (0, 0, 0)
Edge: (0, 0, 0) -> (0, 0.5, 0) また、現状のfinalize_adjacent_to_coplanar_facesでは共有面がカーブしている場合にも捕捉できないと思われます。 add_edgeによる面の分割やShapeOpsStatus選択のロジックが読み解ききれず手を付けられていませんが、そのあたりで面上に辺があるケースを弾く方が正道かもしれません。 |
Trying to solve this, I followed what @tsukimizake said(translated):
So I wrote this function to prevent edges from the coplanar face being recognized as intersection curves and added to the LoopsStore. fn is_coplanar<C>(face0: &C, face1: &C) -> bool
where
C: ParametricSurface3D + Clone,
{
let n0 = face0.normal(0.0, 0.0).normalize();
let n1 = face1.normal(0.0, 0.0).normalize();
if !(n0.dot(n1).abs() - 1.0).so_small() {
return false;
}
let pt0 = face0.subs(0.0, 0.0);
let pt1 = face1.subs(0.0, 0.0);
if !(pt0 - pt1).dot(n0).abs().so_small() {
return false;
}
true
} The change doesn’t seem to break anything (it passes all the tests), but the issue is still there. 😿 |
Here is a minimal example:
When I run this, the output I see is:
I expected the output to be:
If I change the value to:
let z_offset = 0.9
then I get the correct behavior:If I change the value to:
let z_offset = 1.1
then I get different behavior which is also correct:It is only when I choose
let z_offset = 1.0
when the None value is returned. Is this the intended behavior? How can I merge two solids which are touching but not overlapping?The text was updated successfully, but these errors were encountered: