mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-08 13:01:52 +00:00
topology.brep_p1: reuse CopyBrepMap, reference UB-98, final counts after the main merge
The SmCopyBrepMap arguments of sm_SetObjectMap are topology.proto_topology_p1's CopyBrepMap (no duplicate type); the null dereferences met in its SetAt/GetAt are the already recorded UB-98 (the duplicate UB-136/161 entry is withdrawn). Counts after merging origin/main: 2318 cases, 1710 pass, 0 failed, 608 deferred; sweep of 1000 seeds clean; sc-remote green 190 units, 0 failed. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BfiWnWawYvdkvRXZtfC7zK
This commit is contained in:
@@ -21,9 +21,10 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
|
||||
use solidcore::curve::curve::Curve;
|
||||
use solidcore::topology::proto_topology::p1::CopyBrepMap;
|
||||
use solidcore::geom::attribute::{Attribute, AttributeStore, Behavior, ObjectKey};
|
||||
use solidcore::geom::context::MarkType;
|
||||
use solidcore::geom::extent2d::Extent2d;
|
||||
@@ -981,20 +982,32 @@ fn run_rust_op(
|
||||
o.push(bp1::find_highest_vote(&rs, &votes)?.map_or(-1.0, |r| f64::from(r.index())));
|
||||
}
|
||||
OpIn::ObjMap { sets, gets } => {
|
||||
// the copy maps are only asked for stored keys (UB-98, as the shim)
|
||||
let mut map = bp1::ObjectMap::new();
|
||||
let mut copy_map = bp1::CopyBrepMap::new();
|
||||
let mut rev_map = bp1::CopyBrepMap::new();
|
||||
let mut copy_map = CopyBrepMap::<EntityRef>::new();
|
||||
let mut rev_map = CopyBrepMap::<EntityRef>::new();
|
||||
let mut copy_keys = BTreeSet::new();
|
||||
let mut rev_keys = BTreeSet::new();
|
||||
for s in sets {
|
||||
let Some(orig) = entity(s.orig) else {
|
||||
continue;
|
||||
};
|
||||
let copy = entity(s.copy);
|
||||
bp1::set_object_map(
|
||||
orig,
|
||||
entity(s.copy),
|
||||
copy,
|
||||
&mut map,
|
||||
s.copy_map.then_some(&mut copy_map),
|
||||
s.reverse.then_some(&mut rev_map),
|
||||
);
|
||||
if let Some(c) = copy {
|
||||
if s.copy_map {
|
||||
copy_keys.insert(c);
|
||||
}
|
||||
if s.reverse {
|
||||
rev_keys.insert(orig);
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut v: Vec<i64> = Vec::new();
|
||||
for g in gets {
|
||||
@@ -1002,8 +1015,16 @@ fn run_rust_op(
|
||||
let to = from.and_then(|f| bp1::get_object_map(f, &map));
|
||||
v.push(to.map_or(-1, |t| key_of(t).type_code));
|
||||
v.push(to.map_or(-1, index_of));
|
||||
v.push(from.and_then(|f| copy_map.get(&f).copied()).map_or(-1, index_of));
|
||||
v.push(from.and_then(|f| rev_map.get(&f).copied()).map_or(-1, index_of));
|
||||
let c = match from {
|
||||
Some(f) if copy_keys.contains(&f) => copy_map.get_at(Some(f))?,
|
||||
_ => None,
|
||||
};
|
||||
v.push(c.map_or(-1, index_of));
|
||||
let r = match from {
|
||||
Some(f) if rev_keys.contains(&f) => rev_map.get_at(Some(f))?,
|
||||
_ => None,
|
||||
};
|
||||
v.push(r.map_or(-1, index_of));
|
||||
}
|
||||
o.extend(list_of(&v));
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
//! | [`add_attributes`] | `sm_AddAttributes` |
|
||||
//! | [`PendingTopologyDelete`] | `SmPendingTopologyDelete` (`Clear`) |
|
||||
//! | [`make_vertex_split_uv_trim_curve`] | `sm_MakeVertexSplitUVTrimCurve` |
|
||||
//! | [`ObjectMap`], [`set_object_map`], [`get_object_map`] | `sm_SetObjectMap`, `sm_GetObjectMap` |
|
||||
//! | [`ObjectMap`], [`set_object_map`], [`get_object_map`] | `sm_SetObjectMap`, `sm_GetObjectMap` (the copy maps are `topology.proto_topology_p1`'s [`CopyBrepMap`]) |
|
||||
//! | [`reverse_reflection_edgeuses`] | `sm_ReverseReflectionEdgeuses` |
|
||||
//! | [`swap_reflection_shells`] | `sm_SwapReflectionShells` |
|
||||
//! | [`find_side_of_curve`] | `sm_FindSideOfCurve` |
|
||||
@@ -70,10 +70,10 @@
|
||||
//! overflows its stack on a cyclic radial walk; real loop nestings are a handful).
|
||||
//! - `sm_RmAndDel_OldLoopVertices` deletes two vertex uses: the port unlinks them from
|
||||
//! their vertex and resets their records (an arena record cannot be freed).
|
||||
//! - `sm_SetObjectMap` / `sm_GetObjectMap` keep [`EntityRef`] maps ([`ObjectMap`] and
|
||||
//! the optional copy maps are `BTreeMap`s) instead of pointer hash maps (plan hazard
|
||||
//! `ptr-hash`: upstream `SmMapPtrToPtr` iteration order is pointer order; only
|
||||
//! lookups are used here).
|
||||
//! - `sm_SetObjectMap` / `sm_GetObjectMap` keep an [`EntityRef`] `BTreeMap`
|
||||
//! ([`ObjectMap`]) instead of the pointer hash map (plan hazard `ptr-hash`: upstream
|
||||
//! `SmMapPtrToPtr` iteration order is pointer order; only lookups are used here) and
|
||||
//! the ported [`CopyBrepMap`] for the optional copy maps.
|
||||
//! - `SmPendingTopologyDelete`'s destructor work (detaching the pending object's
|
||||
//! attributes and deleting it) runs in `MakeTopologyFromData` (unit
|
||||
//! `topology.brep_p10`); this unit owns only `Clear`.
|
||||
@@ -125,6 +125,7 @@ use crate::topology::edge::{self, AttributeFilter};
|
||||
use crate::topology::edgeuse::p1 as eu1;
|
||||
use crate::topology::face::p2 as face2;
|
||||
use crate::topology::loopuse;
|
||||
use crate::topology::proto_topology::p1::CopyBrepMap;
|
||||
use crate::topology::topology_traverser::{Entity, Marks};
|
||||
use crate::topology::vertex;
|
||||
use crate::topology::vertexuse;
|
||||
@@ -704,26 +705,24 @@ pub fn find_highest_vote(regions: &[RegionId], votes: &[u64]) -> Result<Option<R
|
||||
/// its copy (`None` is a null copy).
|
||||
pub type ObjectMap = BTreeMap<EntityRef, Option<EntityRef>>;
|
||||
|
||||
/// An `SmCopyBrepMap` (copy to original, or original to copy).
|
||||
pub type CopyBrepMap = BTreeMap<EntityRef, EntityRef>;
|
||||
|
||||
/// `sm_SetObjectMap`: records `orig -> copy`, and in the optional copy maps `copy ->
|
||||
/// orig` and `orig -> copy` (a null copy is recorded only in `map`, as upstream keys
|
||||
/// the copy map by the null pointer; the port skips that entry).
|
||||
/// `sm_SetObjectMap`: records `orig -> copy`, and in the optional `SmCopyBrepMap`s
|
||||
/// ([`CopyBrepMap`], unit `topology.proto_topology_p1`) `copy -> orig` and `orig ->
|
||||
/// copy`. A null copy is recorded only in `map`: upstream passes it to
|
||||
/// `SmCopyBrepMap::SetAt`, which dereferences it (UB-98).
|
||||
pub fn set_object_map(
|
||||
orig: EntityRef,
|
||||
copy: Option<EntityRef>,
|
||||
map: &mut ObjectMap,
|
||||
copy_brep_map: Option<&mut CopyBrepMap>,
|
||||
reverse_map: Option<&mut CopyBrepMap>,
|
||||
copy_brep_map: Option<&mut CopyBrepMap<EntityRef>>,
|
||||
reverse_map: Option<&mut CopyBrepMap<EntityRef>>,
|
||||
) {
|
||||
// Use a map object track relationships.
|
||||
map.insert(orig, copy);
|
||||
if let (Some(m), Some(c)) = (copy_brep_map, copy) {
|
||||
m.insert(c, orig);
|
||||
m.set_at(c, orig);
|
||||
}
|
||||
if let (Some(m), Some(c)) = (reverse_map, copy) {
|
||||
m.insert(orig, c);
|
||||
m.set_at(orig, c);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2472,7 +2471,8 @@ mod tests {
|
||||
set_object_map(c, None, &mut map, Some(&mut copy), None);
|
||||
assert_eq!(get_object_map(a, &map), Some(c));
|
||||
assert_eq!(get_object_map(c, &map), None);
|
||||
assert_eq!(copy.get(&c), Some(&a));
|
||||
assert_eq!(rev.get(&a), Some(&c));
|
||||
assert_eq!(copy.get_at(Some(c)).unwrap(), Some(a));
|
||||
assert_eq!(rev.get_at(Some(a)).unwrap(), Some(c));
|
||||
assert_eq!(copy.len(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1000,7 +1000,7 @@ void run_op(int32_t op, Rd& rd, const char* path, std::vector<double>& o)
|
||||
SmCopyBrepMap& copy_map = *pcopy;
|
||||
SmCopyBrepMap& rev_map = *prev;
|
||||
// SmCopyBrepMap::SetAt dereferences a null copy and GetAt its (null) result on a
|
||||
// miss (UB-136): the copy maps only see non-null copies and are only asked for
|
||||
// miss (UB-98): the copy maps only see non-null copies and are only asked for
|
||||
// keys that were stored
|
||||
std::set<const void*> copy_keys, rev_keys;
|
||||
int64_t n_set = rd.idx();
|
||||
|
||||
+7
-10
@@ -5585,19 +5585,16 @@ with the runner-only profile override. No platform prerequisites enter this PR.
|
||||
|
||||
Difftest (`fixtures/topology.brep_p1/`: 2070 cases on the 15 upstream `.smb` files read by
|
||||
`SmBrep::ReadFromFile`, 232 on constructed B-reps (wire edges, plane and B-spline faces,
|
||||
the `prog_test` wire network), 10 `sm_FindSideOfCurve` cases, 16 generated): 2318 cases, 1708 pass, 0 fail, 610 deferred
|
||||
(topology.shell 148, topology.edgeuse_p3 105, topology.brep_p7 88, query.brep 71,
|
||||
surface.surf_of_extrusion_p2 47, surface.sphere 43, surface.cone_p1 29, topology.face_p3 18,
|
||||
topology.face_p1 16, surface.surface_cache_p1 16, heal.heal_data_p1 15, surface.surface_p8 10,
|
||||
curve.crv_on_surf 4); `--perturb` SENSITIVE 1708/1708; a 1000-seed sweep of the generated cases
|
||||
the `prog_test` wire network), 10 `sm_FindSideOfCurve` cases, 16 generated): 2318 cases, 1710 pass, 0 fail, 608 deferred (after merging main at
|
||||
`origin/main` 2026-10-16 evening: topology.shell 148, topology.edgeuse_p3 105, topology.brep_p7 88, query.brep 71, surface.surf_of_extrusion_p2 47, surface.sphere 43, surface.cone_p1 29, topology.face_p3 18, surface.surface_cache_p1 16, topology.face_p1 16, heal.heal_data_p1 15, intersect.curve_class_p4 7, curve.crv_on_surf 4, intersect.surface_drop_curve 1); `--perturb` SENSITIVE 1710/1710; a 1000-seed sweep of the generated cases
|
||||
(3302 cases) passes 2389 with 0 failures.
|
||||
Every compared value is bit-identical; no absolute floors. Of the passes, 15 are `cases_both_errored`
|
||||
(both sides `no_entity`: face ops on the constructed wire B-reps); the other 1693 compare values.
|
||||
(both sides `no_entity`: face ops on the constructed wire B-reps); the other 1695 compare values.
|
||||
|
||||
- **Upstream defect UB-136** (`plan/upstream-issues.md`): `SmCopyBrepMap::SetAt` with a null copy
|
||||
and `GetAt` of a key never stored both dereference null through the release `SM_ASSERT`
|
||||
(`if(a) {}` still evaluates `pOrigObj->GetType()`); `sm_SetObjectMap` documents a null copy as
|
||||
allowed. Confirmed with gdb. The Rust copy maps are `BTreeMap`s (no entry for a null copy, `None`
|
||||
- **Upstream defect UB-98** (already in `plan/upstream-issues.md`, met again here): `SmCopyBrepMap::SetAt`
|
||||
with a null copy and `GetAt` of a key never stored both dereference null through the release
|
||||
`SM_ASSERT` (`if(a) {}` still evaluates `pOrigObj->GetType()`); `sm_SetObjectMap` documents a null
|
||||
copy as allowed. Reproduced with gdb (SIGSEGV in `GetAt`, then in `SetAt`). The Rust copy maps are `BTreeMap`s (no entry for a null copy, `None`
|
||||
on a miss); the shim only exercises the defined inputs.
|
||||
- **List order.** `GetFaces` / `GetEdges` / `GetVertices` return the B-rep's `m_p*ListHead` list
|
||||
order, which differs from the traversal order the shared graph export numbers entities in
|
||||
|
||||
+1
-1
@@ -2800,7 +2800,7 @@ tests = ["prog_test:my_test_extent3d", "prog_test:my_test_vector2d", "prog_test:
|
||||
status = "partial"
|
||||
claimed_by = "bluecmd (Claude Fable 5.1; PR #145)"
|
||||
claimed_at = "2026-10-16"
|
||||
notes = "PARTIAL (PR #145): difftest 2318 cases (2070 fixtures on the 15 upstream .smb files, 232 on constructed B-reps, 16 generated), 1708 pass bit-identical (15 of them both-errored no_entity cases), 0 failed, 610 deferred (topology.shell 148, topology.edgeuse_p3 105, topology.brep_p7 88 (analytic geometry imported as B-spline parts), query.brep 71, surface.surf_of_extrusion_p2 47, surface.sphere 43, surface.cone_p1 29, topology.face_p3 18, topology.face_p1 16, surface.surface_cache_p1 16, heal.heal_data_p1 15, surface.surface_p8 10, curve.crv_on_surf 4), max_rel_err 0, --perturb SENSITIVE 1708/1708; a 1000-seed generated sweep (3302 cases) passes 2389, 0 failed, 913 deferred. All 50 fns have Rust bodies; calls into topology.shell (#154), topology.edgeuse_p3 (#117), topology.face_p1 (#148), topology.face_p3 (#139), query.brep, heal.heal_data_p1 and surface.surface_p8 are UNPORTED stubs. Adds to topology::Brep the SmBrep-owned members (infinite region, region list head, editing flag, size estimates, deleted surfaces, explicit face/edge/vertex list order). Upstream defect UB-136 (SmCopyBrepMap::SetAt/GetAt null deref). Incoming UNPORTED(topology.brep_p1) stubs in other units are not wired in this PR (they hold opaque object handles or SmTol dispatch; see findings). 50 fns; largest: SmBrep::HealBrep, SmBrep::CreateCornerBlend, SmBrep::CreateEdgeEdgeBlend, sm_MakeVertexSplitUVTrimCurve; cycle back-edges (call into later units; stub or co-port): query.brep(3), heal.heal_data_p1(2); unit-SCC #22 (220 units); hazards: ptr-hash; 319 upstream test entry points reach this unit; CO-PORTED in topology.edgeuse_p1 (PR #55): SmBrep::m_bValidateOnly, the region/face use/loop use/edge use/vertex use arenas -> topology::Brep (validate_only, regions(), faceuses(), ..., add_*_record, *_mut); CO-PORTED in topology.edgeuse_p2 (PR #87): SmBrep::m_sThisZoneTol3d, GetTolerance -> topology::Brep::tolerance, set_tolerance"
|
||||
notes = "PARTIAL (PR #145): difftest 2318 cases (2070 fixtures on the 15 upstream .smb files, 232 on constructed B-reps, 16 generated), 1710 pass bit-identical (15 of them both-errored no_entity cases), 0 failed, 608 deferred (topology.shell 148, topology.edgeuse_p3 105, topology.brep_p7 88, query.brep 71, surface.surf_of_extrusion_p2 47, surface.sphere 43, surface.cone_p1 29, topology.face_p3 18, surface.surface_cache_p1 16, topology.face_p1 16, heal.heal_data_p1 15, intersect.curve_class_p4 7, curve.crv_on_surf 4, intersect.surface_drop_curve 1; brep_p7 = analytic geometry imported as B-spline parts), max_rel_err 0, --perturb SENSITIVE 1710/1710; a 1000-seed generated sweep (3302 cases) passes 2389, 0 failed, 913 deferred. All 50 fns have Rust bodies; calls into topology.shell (#154), topology.edgeuse_p3 (#117), topology.face_p1 (#148), topology.face_p3 (#139), query.brep, heal.heal_data_p1 and surface.surface_p8 are UNPORTED stubs. Adds to topology::Brep the SmBrep-owned members (infinite region, region list head, editing flag, size estimates, deleted surfaces, explicit face/edge/vertex list order). Upstream defect UB-98 (SmCopyBrepMap::SetAt/GetAt null deref) met again, reproduced with gdb. Incoming UNPORTED(topology.brep_p1) stubs in other units are not wired in this PR (they hold opaque object handles or SmTol dispatch; see findings). 50 fns; largest: SmBrep::HealBrep, SmBrep::CreateCornerBlend, SmBrep::CreateEdgeEdgeBlend, sm_MakeVertexSplitUVTrimCurve; cycle back-edges (call into later units; stub or co-port): query.brep(3), heal.heal_data_p1(2); unit-SCC #22 (220 units); hazards: ptr-hash; 319 upstream test entry points reach this unit; CO-PORTED in topology.edgeuse_p1 (PR #55): SmBrep::m_bValidateOnly, the region/face use/loop use/edge use/vertex use arenas -> topology::Brep (validate_only, regions(), faceuses(), ..., add_*_record, *_mut); CO-PORTED in topology.edgeuse_p2 (PR #87): SmBrep::m_sThisZoneTol3d, GetTolerance -> topology::Brep::tolerance, set_tolerance"
|
||||
|
||||
[[unit]]
|
||||
id = "topology.brep_p6"
|
||||
|
||||
@@ -1252,15 +1252,6 @@ meantime, whoever merges renumbers the new entry and every reference to it (here
|
||||
- **Confirmed:** yes (the script was run on the C++ reference; the case `edge_proto_p3_rejected_duplicate_manager_entry_0`/`_1` now refuses it on both sides).
|
||||
- **Severity:** crash/UB.
|
||||
- **Rust port:** proto edges are arena ids that are never freed, so the repeat reads a deleted-edge slot and finds no group; nothing is read after free.
|
||||
#### UB-136. `SmCopyBrepMap::SetAt` / `GetAt` dereference null through their release asserts
|
||||
- **Location:** `source/SMLib/src/SmCopyBrepMap.cpp:21-29` `SmCopyBrepMap::SetAt` (`SM_ASSERT(pCopyObj->GetType() == pOrigObj->GetType())`) and `:48-68` `SmCopyBrepMap::GetAt` (the same assert after `m_sMap.At(pCopyObj)`).
|
||||
- **What happens:** the release `SM_ASSERT` (`if(a) {}`, `SmMessages.h:714`) still evaluates its argument. `SetAt` with a null copy (`sm_SetObjectMap`, `SmBrep.cpp:22802`, documents `pCopyObj` "can be NULL" and passes it straight to `SetAt`) and `GetAt` with a key that was never stored (`At` returns `nullptr`) both make a virtual `GetType` call through a null pointer (the compiler emits a load from address 0): SIGSEGV.
|
||||
- **Trigger:** `sm_SetObjectMap(orig, NULL, map, ©Map, ..)`; `GetAt` with any topology pointer not stored in the map (e.g. an original-side pointer asked of the copy-to-original map).
|
||||
- **How found:** difftest of unit `topology.brep_p1` (`sm_SetObjectMap` / `sm_GetObjectMap` cases querying the optional `SmCopyBrepMap`s); backtrace under gdb.
|
||||
- **Confirmed:** yes (release build, gdb: faulting instruction `mov 0x0,%rax` right after the `GetType` call in `SmCopyBrepMap::GetAt`).
|
||||
- **Severity:** crash/UB.
|
||||
- **Rust port:** the copy maps are `BTreeMap`s (`topology::brep::p1::CopyBrepMap`); a null copy is not recorded in them and a missed lookup is `None`. The difftest shim passes the copy maps only for non-null copies and asks `GetAt` only for stored keys.
|
||||
|
||||
#### UB-136. Fillet geometry substitution reads a missing partner interval
|
||||
- **Location:** `source/SMLib/src/SmCurveClass.cpp:16830` (`sm_SetDoFilletingGeometry`), called by `SmCurveClassification::MergeInterval`; unchecked indexing in `source/SMLib/inc/SmCurveClass.h:508`.
|
||||
- **What happens:** Fillet merging indexes both classifications at the target interval without checking the paired classification's size. An empty partner yields a null read; a shorter partner permits an out-of-range interval read.
|
||||
|
||||
@@ -1353,8 +1353,8 @@
|
||||
},
|
||||
{
|
||||
"deferred": {
|
||||
"symbol": "SmSurface::GlobalCurveIntersect",
|
||||
"unit": "surface.surface_p8"
|
||||
"symbol": "SmSurfaceDropCurve::DoTrace",
|
||||
"unit": "intersect.surface_drop_curve"
|
||||
},
|
||||
"max_rel_err": 0.0,
|
||||
"name": "face_bspline_parallel_proj",
|
||||
@@ -1676,16 +1676,12 @@
|
||||
"values_compared": 34
|
||||
},
|
||||
{
|
||||
"deferred": {
|
||||
"symbol": "SmSurface::GlobalCurveIntersect",
|
||||
"unit": "surface.surface_p8"
|
||||
},
|
||||
"max_rel_err": 0.0,
|
||||
"name": "face_bspline_sub_parallel_proj",
|
||||
"outcome": "deferred",
|
||||
"pass": false,
|
||||
"outcome": "pass",
|
||||
"pass": true,
|
||||
"source": "fixture:fixtures/topology.brep_p1/constructed.json#193 (upstream TestFiles/pt_TestFiles/constructed (SmBrep::ReadFromFile))",
|
||||
"values_compared": 0
|
||||
"values_compared": 4
|
||||
},
|
||||
{
|
||||
"max_rel_err": 0.0,
|
||||
@@ -4450,8 +4446,8 @@
|
||||
},
|
||||
{
|
||||
"deferred": {
|
||||
"symbol": "SmSurface::GlobalCurveIntersect",
|
||||
"unit": "surface.surface_p8"
|
||||
"symbol": "SmCurveClassification::SmCurveClassification",
|
||||
"unit": "intersect.curve_class_p4"
|
||||
},
|
||||
"max_rel_err": 0.0,
|
||||
"name": "Endcap_parallel_proj_0",
|
||||
@@ -4469,21 +4465,17 @@
|
||||
"values_compared": 4
|
||||
},
|
||||
{
|
||||
"deferred": {
|
||||
"symbol": "SmSurface::GlobalCurveIntersect",
|
||||
"unit": "surface.surface_p8"
|
||||
},
|
||||
"max_rel_err": 0.0,
|
||||
"name": "Endcap_parallel_proj_2",
|
||||
"outcome": "deferred",
|
||||
"pass": false,
|
||||
"outcome": "pass",
|
||||
"pass": true,
|
||||
"source": "fixture:fixtures/topology.brep_p1/upstream_files.json#272 (upstream TestFiles/pt_TestFiles/Endcap.smb (SmBrep::ReadFromFile))",
|
||||
"values_compared": 0
|
||||
"values_compared": 1
|
||||
},
|
||||
{
|
||||
"deferred": {
|
||||
"symbol": "SmSurface::GlobalCurveIntersect",
|
||||
"unit": "surface.surface_p8"
|
||||
"symbol": "SmCurveClassification::SmCurveClassification",
|
||||
"unit": "intersect.curve_class_p4"
|
||||
},
|
||||
"max_rel_err": 0.0,
|
||||
"name": "Endcap_parallel_proj_3",
|
||||
@@ -4494,8 +4486,8 @@
|
||||
},
|
||||
{
|
||||
"deferred": {
|
||||
"symbol": "SmSurface::GlobalCurveIntersect",
|
||||
"unit": "surface.surface_p8"
|
||||
"symbol": "SmCurveClassification::SmCurveClassification",
|
||||
"unit": "intersect.curve_class_p4"
|
||||
},
|
||||
"max_rel_err": 0.0,
|
||||
"name": "Endcap_parallel_proj_cubic",
|
||||
@@ -9378,8 +9370,8 @@
|
||||
},
|
||||
{
|
||||
"deferred": {
|
||||
"symbol": "SmSurface::GlobalCurveIntersect",
|
||||
"unit": "surface.surface_p8"
|
||||
"symbol": "SmCurveClassification::SmCurveClassification",
|
||||
"unit": "intersect.curve_class_p4"
|
||||
},
|
||||
"max_rel_err": 0.0,
|
||||
"name": "ellips_ts2_parallel_proj_0",
|
||||
@@ -9390,8 +9382,8 @@
|
||||
},
|
||||
{
|
||||
"deferred": {
|
||||
"symbol": "SmSurface::GlobalCurveIntersect",
|
||||
"unit": "surface.surface_p8"
|
||||
"symbol": "SmCurveClassification::SmCurveClassification",
|
||||
"unit": "intersect.curve_class_p4"
|
||||
},
|
||||
"max_rel_err": 0.0,
|
||||
"name": "ellips_ts2_parallel_proj_1",
|
||||
@@ -9410,8 +9402,8 @@
|
||||
},
|
||||
{
|
||||
"deferred": {
|
||||
"symbol": "SmSurface::GlobalCurveIntersect",
|
||||
"unit": "surface.surface_p8"
|
||||
"symbol": "SmCurveClassification::SmCurveClassification",
|
||||
"unit": "intersect.curve_class_p4"
|
||||
},
|
||||
"max_rel_err": 0.0,
|
||||
"name": "ellips_ts2_parallel_proj_3",
|
||||
@@ -9422,8 +9414,8 @@
|
||||
},
|
||||
{
|
||||
"deferred": {
|
||||
"symbol": "SmSurface::GlobalCurveIntersect",
|
||||
"unit": "surface.surface_p8"
|
||||
"symbol": "SmCurveClassification::SmCurveClassification",
|
||||
"unit": "intersect.curve_class_p4"
|
||||
},
|
||||
"max_rel_err": 0.0,
|
||||
"name": "ellips_ts2_parallel_proj_cubic",
|
||||
@@ -21002,19 +20994,20 @@
|
||||
}
|
||||
],
|
||||
"cases_both_errored": 15,
|
||||
"cases_deferred": 610,
|
||||
"cases_deferred": 608,
|
||||
"cases_failed": 0,
|
||||
"cases_passed": 1708,
|
||||
"cases_passed": 1710,
|
||||
"cases_total": 2318,
|
||||
"deferred_by_unit": {
|
||||
"curve.crv_on_surf": 4,
|
||||
"heal.heal_data_p1": 15,
|
||||
"intersect.curve_class_p4": 7,
|
||||
"intersect.surface_drop_curve": 1,
|
||||
"query.brep": 71,
|
||||
"surface.cone_p1": 29,
|
||||
"surface.sphere": 43,
|
||||
"surface.surf_of_extrusion_p2": 47,
|
||||
"surface.surface_cache_p1": 16,
|
||||
"surface.surface_p8": 10,
|
||||
"topology.brep_p7": 88,
|
||||
"topology.edgeuse_p3": 105,
|
||||
"topology.face_p1": 16,
|
||||
|
||||
Reference in New Issue
Block a user