Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 85 additions & 22 deletions crates/solidcore/src/query/brep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@

mod ray;

pub(crate) use ray::solve_mutable_brep_point;
#[cfg(test)]
pub(crate) use ray::PreparationRequest;
pub use ray::RayPreparation;
Expand Down Expand Up @@ -453,7 +454,7 @@ impl<'a> BrepQuery<'a> {
tolerance,
None,
|b, point, options| {
ray::solve_mutable_brep_point(k, b, &self.identity, cache, point, options)
solve_mutable_brep_point(k, b, &self.identity, cache, point, options)
},
)
}
Expand Down Expand Up @@ -511,30 +512,39 @@ impl<'a> BrepQuery<'a> {

// Intersect the point with the boundary elements of the Brep
if do_boundary_intersections {
let b = target.shared();
let objects = BrepObjects {
preparation: None,
brep: b,
brep_id,
cache: Some(self.cache(k, b)?),
keys,
owner_of,
let options = TopologySolveOptions {
operation: SolverOperation::Intersect,
requested: SolutionRequested::Single,
tolerance_3d: point_zone_tol_3d,
best_answer_so_far_sq: 0.0,
opt_vectors: &[],
};
// XSects point with the Brep verts, edges, and faces returning lowest dim
// topology intersection found.
let solutions = TopologySolver::brep_point_solve(
k,
&objects,
Some(CacheObject::Brep),
point,
TopologySolveOptions {
operation: SolverOperation::Intersect,
requested: SolutionRequested::Single,
tolerance_3d: point_zone_tol_3d,
best_answer_so_far_sq: 0.0,
opt_vectors: &[],
},
)?;
let solutions = match &mut target {
Target::Own(b) => {
let cache = self.cache(k, b)?;
solve_mutable_brep_point(k, b, &self.identity, cache, point, options)?
}
Target::Shared { .. } => {
let b = target.shared();
let objects = BrepObjects {
preparation: None,
brep: b,
brep_id,
cache: Some(self.cache(k, b)?),
keys,
owner_of,
};
TopologySolver::brep_point_solve(
k,
&objects,
Some(CacheObject::Brep),
point,
options,
)?
}
};

// when the point is on a Brep Face
if let Some(sol) = solutions.get(0) {
Expand Down Expand Up @@ -1128,6 +1138,59 @@ mod tests {
assert_eq!(format!("{b:?}"), before);
}

/// A unit box from `create_box` without its UV trims (upstream's classification
/// makes the ones its loop walks reach), and a query under the box's own keys
/// (`notify_ref`, as `create_box` owns its geometry).
fn box_without_trims(k: &mut Kernel) -> (Brep, BrepQuery<'static>) {
fn keys(o: CacheObject) -> ObjectRef {
use crate::topology::loopuse::notify_ref;
match o {
CacheObject::Edge(e) | CacheObject::Curve(e) => notify_ref(EntityRef::Edge(e)),
CacheObject::Face(f) | CacheObject::Surface(f) => notify_ref(EntityRef::Face(f)),
CacheObject::Vertex(v) => notify_ref(EntityRef::Vertex(v)),
_ => notify_ref(EntityRef::Brep(BrepId::from_index(0))),
}
}
fn no_owner(_: ObjectRef) -> Option<ObjectRef> {
None
}
let mut b =
crate::primitive::api_primitives::create_box(k, Point3::ZERO, 1.0, 1.0, 1.0).unwrap();
let uses: Vec<_> = b.edgeuses().ids().collect();
for u in uses {
b.edgeuse_mut(u).unwrap().uv_trim_curve = None;
}
let query = BrepQuery::new(BrepIdentity {
brep_id: BrepId::from_index(0),
keys: &keys,
owner_of: &no_owner,
});
(b, query)
}

fn trim_count(b: &Brep) -> usize {
b.edgeuses()
.iter()
.filter(|(_, u)| u.uv_trim_curve.is_some())
.count()
}

#[test]
fn ray_fires_make_missing_uv_trims_on_the_callers_brep() {
let mut k = Kernel::default();
let (mut b, query) = box_without_trims(&mut k);
let solid = b
.regions()
.ids()
.find(|&r| Some(r) != b.infinite_region())
.map(EntityRef::Region);
let inside = query
.point_3d_classify(&k, &mut b, Point3::new(0.5, 0.5, 0.5), 1e-6, false)
.unwrap();
assert_eq!(inside.object(), solid);
assert!(trim_count(&b) > 0, "the trims are made on the box itself");
}

#[test]
fn lazy_brep_edits_the_callers_brep_or_a_copy() {
let mut b = Brep::new();
Expand Down
10 changes: 3 additions & 7 deletions crates/solidcore/src/topology/brep/p2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ use crate::intersect::curve_class::ClassificationInit;
use crate::intersect::point_class::{
ClassGeometry, ClassObject, PointClassType, PointClassification,
};
use crate::intersect::topology_solver::p1::TopologySolver;
use crate::intersect::topology_solver::p2::TopologySolveOptions;
use crate::kernel::Kernel;
use crate::math::{Point2, Point3, Vec3, BIG_DOUBLE, EFF_ZERO, EFF_ZERO_SQRT, PI};
Expand All @@ -105,7 +104,7 @@ use crate::query::face::p2::{curve_on_classify, CurveOnClassifyObjects};
use crate::surface::surface::{Surface, SurfaceKind};
use crate::surface::trim_srf_cache::TrimSrfCache;
use crate::topology::brep::p1;
use crate::topology::brep_cache::{self, BrepCache, BrepObjects, CacheObject, CacheSource};
use crate::topology::brep_cache::{self, BrepCache, CacheObject, CacheSource};
use crate::topology::edge::{self, AttributeFilter, NotifyEnv, SetCurveOptions};
use crate::topology::edgeuse::p1::{self as eu1, UvTrimCurveArg};
use crate::topology::edgeuse::p2 as eu2;
Expand Down Expand Up @@ -1347,15 +1346,12 @@ pub fn ray_fire(
ray_zone_tol_3d,
answer_limit,
|b, point, options| {
let objects = BrepObjects {
preparation: None,
brep: b,
let identity = crate::query::brep::BrepIdentity {
brep_id,
cache: Some(cache),
keys,
owner_of,
};
TopologySolver::brep_point_solve(k, &objects, Some(CacheObject::Brep), point, options)
crate::query::brep::solve_mutable_brep_point(k, b, &identity, cache, point, options)
},
)
}
Expand Down
Loading