first commit
This commit is contained in:
@@ -0,0 +1,826 @@
|
||||
using SolidWorks.Interop.sldworks;
|
||||
|
||||
static class AssemblyModelProcessing
|
||||
{
|
||||
public static List<ComponentHighlightImageRequest> BuildComponentHighlightImageRequests(SectionBrepReport report)
|
||||
{
|
||||
var componentsById = report.AssemblyComponents
|
||||
.ToDictionary(component => component.Id, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
var designTargets = report.PartImagePlan
|
||||
.Where(item => !string.IsNullOrWhiteSpace(item.ComponentId))
|
||||
.Where(item => IsTopLevelAssemblyComponent(item.InstanceName))
|
||||
.GroupBy(item => item.ComponentId, StringComparer.OrdinalIgnoreCase)
|
||||
.Select(group => group.First())
|
||||
.Select(item => new ComponentHighlightImageRequest
|
||||
{
|
||||
PlanId = item.AssemblyContextImagePlanId,
|
||||
ComponentId = item.ComponentId,
|
||||
InstanceName = item.InstanceName,
|
||||
DisplayName = item.DisplayName,
|
||||
ComponentPath = item.ComponentPath,
|
||||
Views = ["best_oblique"],
|
||||
PreferredDirectionMm = componentsById.TryGetValue(item.ComponentId, out var component)
|
||||
? ChooseComponentHighlightDirection(component, report.AssemblyComponents)
|
||||
: [],
|
||||
ShowComponents =
|
||||
[
|
||||
BuildComponentImageRef(
|
||||
componentsById.GetValueOrDefault(item.ComponentId),
|
||||
item.InstanceName,
|
||||
item.DisplayName,
|
||||
item.ComponentPath)
|
||||
]
|
||||
})
|
||||
.ToList();
|
||||
|
||||
return designTargets;
|
||||
}
|
||||
|
||||
static bool IsTopLevelAssemblyComponent(string instanceName)
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(instanceName) &&
|
||||
!instanceName.Contains("/", StringComparison.Ordinal) &&
|
||||
!instanceName.Contains("\\", StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
public static List<ComponentContextImageRequest> BuildComponentContextImageRequests(SectionBrepReport report)
|
||||
{
|
||||
var componentsById = report.AssemblyComponents
|
||||
.ToDictionary(component => component.Id, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
return report.ComponentContextImagePlan
|
||||
.Where(item => ShouldExportComponentContext(item, report.ExternalInterfaceRoots))
|
||||
.Where(item => item.ShowComponents.Count > 0)
|
||||
.Select(item =>
|
||||
{
|
||||
var showComponents = item.ShowComponents
|
||||
.Select(component => BuildComponentImageRef(component, componentsById))
|
||||
.ToList();
|
||||
var preserveComponents = item.BoundaryComponents
|
||||
.Select(component => BuildComponentImageRef(component, componentsById))
|
||||
.ToList();
|
||||
var protectedIds = showComponents
|
||||
.Concat(preserveComponents)
|
||||
.Select(component => component.ComponentId)
|
||||
.ToHashSet(StringComparer.OrdinalIgnoreCase);
|
||||
var hideComponents = item.MemberOcclusionAnalyses
|
||||
.SelectMany(analysis => analysis.Directions)
|
||||
.Where(direction => direction.Occluded)
|
||||
.SelectMany(direction => direction.FirstHitComponents)
|
||||
.Where(blocker => !protectedIds.Contains(blocker.ComponentId))
|
||||
.DistinctBy(blocker => $"{blocker.InstanceName}::{blocker.ComponentPath}", StringComparer.OrdinalIgnoreCase)
|
||||
.Select(blocker => new ComponentImageRef
|
||||
{
|
||||
ComponentId = blocker.ComponentId,
|
||||
InstanceName = blocker.InstanceName,
|
||||
DisplayName = blocker.DisplayName,
|
||||
ComponentPath = blocker.ComponentPath,
|
||||
BBoxMm = componentsById.TryGetValue(blocker.ComponentId, out var blockerSummary)
|
||||
? blockerSummary.BBoxMm
|
||||
: []
|
||||
})
|
||||
.ToList();
|
||||
|
||||
return new ComponentContextImageRequest
|
||||
{
|
||||
PlanId = item.Id,
|
||||
GroupId = item.GroupId,
|
||||
TargetComponentId = item.TargetComponentId,
|
||||
TargetInstanceName = item.TargetInstanceName,
|
||||
TargetDisplayName = item.TargetDisplayName,
|
||||
TargetComponentPath = item.TargetComponentPath,
|
||||
Views = ["best_oblique"],
|
||||
PreferredDirectionMm = componentsById.TryGetValue(item.TargetComponentId, out var component)
|
||||
? ChooseComponentHighlightDirection(component, report.AssemblyComponents)
|
||||
: [],
|
||||
ShowComponents = showComponents,
|
||||
PreserveComponents = preserveComponents,
|
||||
HideComponents = hideComponents
|
||||
};
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
|
||||
static bool ShouldExportComponentContext(ComponentContextImagePlanItem item, IReadOnlyList<string> externalInterfaceRoots)
|
||||
{
|
||||
if (externalInterfaceRoots.Count == 0)
|
||||
return true;
|
||||
|
||||
// Purchased-component hints are semantic hints, not a switch to disable
|
||||
// all component context images. But ordinary component-context images
|
||||
// should not expand the inside of a user-specified purchased module.
|
||||
// Those internal contacts are represented by physical-interface images
|
||||
// when they cross the purchased-module boundary.
|
||||
return !IsExternalInterfaceRootDescendant(item.TargetInstanceName, item.TargetComponentPath, externalInterfaceRoots);
|
||||
}
|
||||
|
||||
static bool IsExternalInterfaceRootDescendant(string instanceName, string path, IReadOnlyList<string> roots)
|
||||
{
|
||||
var name = NormalizeRootMatchText(instanceName);
|
||||
var strippedName = NormalizeRootMatchText(StripInstanceSuffix(instanceName));
|
||||
var file = NormalizeRootMatchText(Path.GetFileNameWithoutExtension(path));
|
||||
foreach (var root in roots.Select(NormalizeRootMatchText).Where(root => root.Length > 0))
|
||||
{
|
||||
var exactRoot =
|
||||
name.Equals(root, StringComparison.OrdinalIgnoreCase) ||
|
||||
strippedName.Equals(root, StringComparison.OrdinalIgnoreCase) ||
|
||||
file.Equals(root, StringComparison.OrdinalIgnoreCase);
|
||||
if (exactRoot)
|
||||
return false;
|
||||
|
||||
if (name.StartsWith(root + "-", StringComparison.OrdinalIgnoreCase) ||
|
||||
name.StartsWith(root + "/", StringComparison.OrdinalIgnoreCase) ||
|
||||
strippedName.StartsWith(root + "-", StringComparison.OrdinalIgnoreCase) ||
|
||||
strippedName.StartsWith(root + "/", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static List<InterfaceHighlightImageRequest> BuildInterfaceHighlightImageRequests(
|
||||
SectionBrepReport report,
|
||||
int maxRequests = 30,
|
||||
bool compactViews = false)
|
||||
{
|
||||
if (!report.DocumentKind.Equals("assembly", StringComparison.OrdinalIgnoreCase) ||
|
||||
report.AssemblyFaceContacts.Count == 0)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
var components = report.AssemblyComponents;
|
||||
var groups = BuildPhysicalInterfaceGroups(report.AssemblyFaceContacts, report.ExternalInterfaceRoots)
|
||||
.OrderByDescending(group => group.AnalysisPriority)
|
||||
.ThenByDescending(group => group.Contacts.Max(contact => contact.Confidence))
|
||||
.Take(Math.Max(0, maxRequests))
|
||||
.ToList();
|
||||
var requests = new List<InterfaceHighlightImageRequest>();
|
||||
|
||||
foreach (var group in groups)
|
||||
{
|
||||
var contact = group.Contacts[0];
|
||||
var componentA = FindComponentSummary(components, contact.ComponentA, contact.ComponentPathA);
|
||||
var componentB = FindComponentSummary(components, contact.ComponentB, contact.ComponentPathB);
|
||||
var refA = BuildComponentImageRef(componentA, contact.ComponentA, contact.ComponentDisplayNameA, contact.ComponentPathA);
|
||||
var refB = BuildComponentImageRef(componentB, contact.ComponentB, contact.ComponentDisplayNameB, contact.ComponentPathB);
|
||||
var axis = RepresentativeAxis(group.Contacts);
|
||||
var normal = RepresentativeNormal(group.Contacts);
|
||||
var interfaceBox = UnionBoxes(group.Contacts.SelectMany(item => new[] { item.BBoxA, item.BBoxB }));
|
||||
var isCylindrical = contact.ContactKind.Contains("cylindrical", StringComparison.OrdinalIgnoreCase);
|
||||
var verificationStatuses = group.Contacts
|
||||
.Select(item => item.VerificationStatus)
|
||||
.Where(status => !string.IsNullOrWhiteSpace(status))
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
.ToList();
|
||||
|
||||
requests.Add(new InterfaceHighlightImageRequest
|
||||
{
|
||||
PlanId = $"physical_interface_highlight_{SanitizeId(group.Id)}",
|
||||
InterfaceId = group.Id,
|
||||
ContactKind = contact.ContactKind,
|
||||
MateRole = contact.MateRole,
|
||||
ComponentA = refA,
|
||||
ComponentB = refB,
|
||||
FaceARef = group.FaceARefs[0],
|
||||
FaceBRef = group.FaceBRefs[0],
|
||||
FaceAIndex = group.FaceAIndices[0],
|
||||
FaceBIndex = group.FaceBIndices[0],
|
||||
FaceARefs = group.FaceARefs,
|
||||
FaceBRefs = group.FaceBRefs,
|
||||
FaceAIndices = group.FaceAIndices,
|
||||
FaceBIndices = group.FaceBIndices,
|
||||
RuntimeFaces = group.RuntimeFaces,
|
||||
SourceContactIds = group.Contacts.Select(item => item.Id).Distinct(StringComparer.OrdinalIgnoreCase).ToList(),
|
||||
Views = compactViews
|
||||
? ["assembled_oblique"]
|
||||
: isCylindrical
|
||||
? ["assembled_oblique", "axis_end", "axis_side"]
|
||||
: ["assembled_oblique", "normal_view"],
|
||||
PreferredDirectionMm = ChooseInterfaceHighlightDirection(contact, components),
|
||||
InterfaceAxisMm = axis,
|
||||
InterfaceNormalMm = normal,
|
||||
InterfaceCenterMm = AverageCenters(group.Contacts),
|
||||
InterfaceBBoxMm = interfaceBox,
|
||||
AnalysisPriority = group.AnalysisPriority,
|
||||
ConfidenceTier = group.ConfidenceTier,
|
||||
EvidencePurpose = "physical_interface_function_analysis",
|
||||
TrimmedPatchVerified = group.Contacts.All(item => item.TrimmedPatchVerified),
|
||||
VerificationStatus = verificationStatuses.Count == 1
|
||||
? verificationStatuses[0]
|
||||
: "mixed_verified_interface",
|
||||
VerificationMethods = group.Contacts
|
||||
.Select(item => item.VerificationMethod)
|
||||
.Where(method => !string.IsNullOrWhiteSpace(method))
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
.ToList(),
|
||||
VerificationSampleHits = group.Contacts.Sum(item => item.VerificationSampleHits),
|
||||
VerificationMinDistanceMm = group.Contacts.Min(item => item.VerificationMinDistanceMm),
|
||||
DisplayMode = "actual_assembly_position_with_native_selected_interface_faces",
|
||||
ActualAssemblyPosition = true,
|
||||
NotActualClearance = true,
|
||||
ShowComponents = [refA, refB],
|
||||
PreserveComponents = []
|
||||
});
|
||||
}
|
||||
|
||||
return requests;
|
||||
}
|
||||
|
||||
static List<PhysicalInterfaceGroup> BuildPhysicalInterfaceGroups(
|
||||
IReadOnlyList<AssemblyFaceContactEvidence> contacts,
|
||||
IReadOnlyList<string> externalInterfaceRoots)
|
||||
{
|
||||
var planarProfilePairKeys = BuildPlanarProfilePairKeys(contacts);
|
||||
var groups = new List<PhysicalInterfaceGroup>();
|
||||
foreach (var contact in contacts
|
||||
.Where(contact => contact.FaceA > 0 && contact.FaceB > 0)
|
||||
.Where(IsConfirmedInterfaceContact)
|
||||
.Where(contact => IsExternalPurchasedInterfaceContact(contact, externalInterfaceRoots))
|
||||
.Where(contact => ShouldExportFitLikeInterface(contact, planarProfilePairKeys)))
|
||||
{
|
||||
var key = PhysicalInterfaceKey(contact);
|
||||
var group = groups.FirstOrDefault(candidate =>
|
||||
candidate.BaseKey.Equals(key, StringComparison.OrdinalIgnoreCase) &&
|
||||
candidate.Contacts.Any(existing => SamePhysicalInterfaceSegment(existing, contact)));
|
||||
if (group == null)
|
||||
{
|
||||
group = new PhysicalInterfaceGroup
|
||||
{
|
||||
BaseKey = key,
|
||||
Id = $"physical_interface_{groups.Count + 1:000}_{ShortInterfaceToken(contact.ComponentFileNameA, contact.ComponentA)}__{ShortInterfaceToken(contact.ComponentFileNameB, contact.ComponentB)}"
|
||||
};
|
||||
groups.Add(group);
|
||||
}
|
||||
|
||||
// Keep every group oriented like its first contact so face-side identity remains stable.
|
||||
var first = group.Contacts.FirstOrDefault();
|
||||
var sameOrientation = first == null || SameComponentIdentity(first.ComponentA, first.ComponentPathA, contact.ComponentA, contact.ComponentPathA);
|
||||
group.Contacts.Add(contact);
|
||||
if (sameOrientation)
|
||||
{
|
||||
AddFace(group.FaceARefs, group.FaceAIndices, contact.ComponentA, contact.FaceA);
|
||||
AddFace(group.FaceBRefs, group.FaceBIndices, contact.ComponentB, contact.FaceB);
|
||||
AddRuntimeFace(group.RuntimeFaces, contact.RuntimeFaceA);
|
||||
AddRuntimeFace(group.RuntimeFaces, contact.RuntimeFaceB);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddFace(group.FaceARefs, group.FaceAIndices, contact.ComponentB, contact.FaceB);
|
||||
AddFace(group.FaceBRefs, group.FaceBIndices, contact.ComponentA, contact.FaceA);
|
||||
AddRuntimeFace(group.RuntimeFaces, contact.RuntimeFaceB);
|
||||
AddRuntimeFace(group.RuntimeFaces, contact.RuntimeFaceA);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var group in groups)
|
||||
{
|
||||
var text = string.Join(" ", group.Contacts.Select(contact =>
|
||||
$"{contact.ContactKind} {contact.MateRole} {contact.ComponentCategoryA} {contact.ComponentCategoryB} {contact.ComponentDisplayNameA} {contact.ComponentDisplayNameB}"));
|
||||
var containsKnownStandardPart = ContainsAny(text, "bearing", "轴承", "bolt", "screw", "nut", "pin", "key", "螺", "销", "键");
|
||||
var geometryConfidence = group.Contacts.Max(contact => contact.Confidence);
|
||||
group.AnalysisPriority = (containsKnownStandardPart ? 100 : 0)
|
||||
+ (group.Contacts.Any(contact => contact.ContactKind.Contains("cylindrical", StringComparison.OrdinalIgnoreCase)) ? 30 : 10)
|
||||
+ geometryConfidence * 20
|
||||
+ Math.Min(10, group.Contacts.Count);
|
||||
group.ConfidenceTier = containsKnownStandardPart && geometryConfidence >= 0.75
|
||||
? "anchor"
|
||||
: geometryConfidence >= 0.75 ? "high" : geometryConfidence >= 0.45 ? "medium" : "low";
|
||||
}
|
||||
|
||||
return groups;
|
||||
}
|
||||
|
||||
// Physical-interface images are boundary evidence only:
|
||||
// exactly one side must be a purchased/standard component and the other
|
||||
// side must be a top-level external non-purchased component. Internal
|
||||
// purchased-to-purchased or purchased-to-internal contacts remain in the
|
||||
// B-rep contact report but are not exported as physical-interface images.
|
||||
static bool IsExternalPurchasedInterfaceContact(AssemblyFaceContactEvidence contact, IReadOnlyList<string> externalInterfaceRoots)
|
||||
{
|
||||
if (externalInterfaceRoots.Count > 0)
|
||||
{
|
||||
var aIsRoot = IsExternalInterfaceRootMember(contact.ComponentA, contact.ComponentPathA, externalInterfaceRoots);
|
||||
var bIsRoot = IsExternalInterfaceRootMember(contact.ComponentB, contact.ComponentPathB, externalInterfaceRoots);
|
||||
return aIsRoot ^ bIsRoot;
|
||||
}
|
||||
|
||||
var purchasedA = IsPurchasedInterfaceComponent(contact.ComponentCategoryA, contact.ComponentA, contact.ComponentPathA);
|
||||
var purchasedB = IsPurchasedInterfaceComponent(contact.ComponentCategoryB, contact.ComponentB, contact.ComponentPathB);
|
||||
if (purchasedA == purchasedB)
|
||||
return false;
|
||||
|
||||
var externalOther = purchasedA
|
||||
? contact.ComponentB
|
||||
: contact.ComponentA;
|
||||
var otherCategory = purchasedA
|
||||
? contact.ComponentCategoryB
|
||||
: contact.ComponentCategoryA;
|
||||
var otherPath = purchasedA
|
||||
? contact.ComponentPathB
|
||||
: contact.ComponentPathA;
|
||||
return !IsPurchasedInterfaceComponent(otherCategory, externalOther, otherPath) &&
|
||||
IsTopLevelAssemblyComponent(externalOther);
|
||||
}
|
||||
|
||||
static bool IsExternalInterfaceRootMember(string instanceName, string path, IReadOnlyList<string> roots)
|
||||
{
|
||||
var name = NormalizeRootMatchText(instanceName);
|
||||
var strippedName = NormalizeRootMatchText(StripInstanceSuffix(instanceName));
|
||||
var file = NormalizeRootMatchText(Path.GetFileNameWithoutExtension(path));
|
||||
foreach (var root in roots.Select(NormalizeRootMatchText).Where(root => root.Length > 0))
|
||||
{
|
||||
if (name.Equals(root, StringComparison.OrdinalIgnoreCase) ||
|
||||
strippedName.Equals(root, StringComparison.OrdinalIgnoreCase) ||
|
||||
file.Equals(root, StringComparison.OrdinalIgnoreCase) ||
|
||||
name.StartsWith(root + "-", StringComparison.OrdinalIgnoreCase) ||
|
||||
name.StartsWith(root + "/", StringComparison.OrdinalIgnoreCase) ||
|
||||
strippedName.StartsWith(root + "-", StringComparison.OrdinalIgnoreCase) ||
|
||||
strippedName.StartsWith(root + "/", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static string StripInstanceSuffix(string value) =>
|
||||
System.Text.RegularExpressions.Regex.Replace(value ?? "", @"-\d+(?=/|$)", "");
|
||||
|
||||
static string NormalizeRootMatchText(string value) =>
|
||||
(value ?? "").Trim().Replace('\\', '/');
|
||||
|
||||
static bool IsPurchasedInterfaceComponent(string category, string instanceName, string path)
|
||||
{
|
||||
if (category.Equals("bearing", StringComparison.OrdinalIgnoreCase) ||
|
||||
category.Equals("purchased_motor", StringComparison.OrdinalIgnoreCase) ||
|
||||
category.Equals("purchased_reducer", StringComparison.OrdinalIgnoreCase) ||
|
||||
category.Equals("purchased_motor_reducer_assembly", StringComparison.OrdinalIgnoreCase) ||
|
||||
category.Equals("user_purchased_component", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var text = $"{category} {instanceName} {path}".ToLowerInvariant();
|
||||
if (LooksLikeDesignedConnectorOrHousing(text))
|
||||
return false;
|
||||
|
||||
return ContainsAny(
|
||||
text,
|
||||
"gb", "t70", "t276", "bearing", "bolt", "screw",
|
||||
"csg", "shg", "mhc", "ec60", "purchased_motor", "purchased_reducer", "gearbox",
|
||||
"motor", "servo", "reducer", "gear motor",
|
||||
"\u8f74\u627f", "\u87ba\u9489", "\u87ba\u6813", "\u7535\u673a", "\u9a6c\u8fbe", "\u4f3a\u670d", "\u51cf\u901f\u5668", "\u51cf\u901f\u673a");
|
||||
}
|
||||
|
||||
static bool LooksLikeDesignedConnectorOrHousing(string text)
|
||||
{
|
||||
return ContainsAny(
|
||||
text,
|
||||
"\u8fde\u63a5\u4ef6", "\u6cd5\u5170", "\u5916\u58f3", "\u58f3\u4f53", "\u652f\u67b6", "\u5ea7",
|
||||
"connector", "adapter", "bracket", "flange", "housing", "mount");
|
||||
}
|
||||
|
||||
static bool IsConfirmedInterfaceContact(AssemblyFaceContactEvidence contact) =>
|
||||
contact.TrimmedPatchVerified &&
|
||||
(contact.VerificationStatus.Equals("trimmed_interface_confirmed", StringComparison.OrdinalIgnoreCase) ||
|
||||
contact.VerificationStatus.Equals("trimmed_cylindrical_domain_confirmed", StringComparison.OrdinalIgnoreCase) ||
|
||||
contact.VerificationStatus.Equals("analytic_cylindrical_domain_confirmed", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
static string ShortInterfaceToken(string fileName, string componentName)
|
||||
{
|
||||
var token = SanitizeId(FirstNonEmpty(Path.GetFileNameWithoutExtension(fileName), componentName, "component"));
|
||||
return token.Length <= 24 ? token : token[..24];
|
||||
}
|
||||
|
||||
static bool SamePhysicalInterfaceSegment(AssemblyFaceContactEvidence a, AssemblyFaceContactEvidence b)
|
||||
{
|
||||
if (!a.ContactKind.Contains("cylindrical", StringComparison.OrdinalIgnoreCase) ||
|
||||
!b.ContactKind.Contains("cylindrical", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var axis = a.AxisA.Length >= 3 ? Vec.Normalize(a.AxisA) : Vec.Normalize(a.AxisB);
|
||||
if (axis.Length < 3)
|
||||
return true;
|
||||
var intervalA = ContactAxialInterval(a, axis);
|
||||
var intervalB = ContactAxialInterval(b, axis);
|
||||
if (!intervalA.HasValue || !intervalB.HasValue)
|
||||
return true;
|
||||
var radius = new[] { a.RadiusAmm, a.RadiusBmm, b.RadiusAmm, b.RadiusBmm }.Where(value => value > 0).DefaultIfEmpty(1).Average();
|
||||
var allowedGap = Math.Max(0.5, radius * 0.03);
|
||||
return intervalA.Value.Min <= intervalB.Value.Max + allowedGap &&
|
||||
intervalB.Value.Min <= intervalA.Value.Max + allowedGap;
|
||||
}
|
||||
|
||||
static (double Min, double Max)? ContactAxialInterval(AssemblyFaceContactEvidence contact, double[] axis)
|
||||
{
|
||||
var boxes = new[] { contact.BBoxA, contact.BBoxB }.Where(box => box.Length >= 6).ToList();
|
||||
if (boxes.Count == 0)
|
||||
return null;
|
||||
var values = boxes.SelectMany(BoxCorners).Select(point => Vec.Dot(point, axis)).ToList();
|
||||
return (values.Min(), values.Max());
|
||||
}
|
||||
|
||||
static string PhysicalInterfaceKey(AssemblyFaceContactEvidence contact)
|
||||
{
|
||||
var pair = ComponentPairKey(
|
||||
FirstNonEmpty(contact.ComponentPathA, contact.ComponentA),
|
||||
FirstNonEmpty(contact.ComponentPathB, contact.ComponentB));
|
||||
if (!contact.ContactKind.Contains("cylindrical", StringComparison.OrdinalIgnoreCase))
|
||||
return $"{pair}|planar_profile";
|
||||
|
||||
var axis = contact.AxisA.Length >= 3 ? Vec.Normalize(contact.AxisA) : Vec.Normalize(contact.AxisB);
|
||||
axis = CanonicalDirection(axis);
|
||||
var radius = new[] { contact.RadiusAmm, contact.RadiusBmm }.Where(value => value > 0).DefaultIfEmpty(0).Average();
|
||||
var center = AverageVectors(contact.CenterA, contact.CenterB);
|
||||
var axisOffset = axis.Length >= 3 && center.Length >= 3
|
||||
? Vec.Sub(center, Vec.Mul(axis, Vec.Dot(center, axis)))
|
||||
: [];
|
||||
return string.Join("|", new[]
|
||||
{
|
||||
pair,
|
||||
"cylindrical",
|
||||
VectorKey(axis, 0.02),
|
||||
VectorKey(axisOffset, Math.Max(0.1, radius * 0.01)),
|
||||
$"r{Math.Round(radius, 2):0.00}"
|
||||
});
|
||||
}
|
||||
|
||||
static void AddFace(List<string> refs, List<int> indices, string component, int faceIndex)
|
||||
{
|
||||
if (faceIndex <= 0)
|
||||
return;
|
||||
var faceRef = $"{component}:face#{faceIndex}";
|
||||
if (refs.Contains(faceRef, StringComparer.OrdinalIgnoreCase))
|
||||
return;
|
||||
refs.Add(faceRef);
|
||||
indices.Add(faceIndex);
|
||||
}
|
||||
|
||||
static void AddRuntimeFace(List<Face2> faces, Face2? face)
|
||||
{
|
||||
if (face != null && !faces.Any(existing => ReferenceEquals(existing, face)))
|
||||
faces.Add(face);
|
||||
}
|
||||
|
||||
static bool SameComponentIdentity(string nameA, string pathA, string nameB, string pathB) =>
|
||||
!string.IsNullOrWhiteSpace(pathA) && !string.IsNullOrWhiteSpace(pathB)
|
||||
? pathA.Equals(pathB, StringComparison.OrdinalIgnoreCase)
|
||||
: nameA.Equals(nameB, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
static double[] RepresentativeAxis(IReadOnlyList<AssemblyFaceContactEvidence> contacts) =>
|
||||
contacts.Select(contact => contact.AxisA.Length >= 3 ? contact.AxisA : contact.AxisB)
|
||||
.FirstOrDefault(axis => axis.Length >= 3) is { Length: >= 3 } axis ? CanonicalDirection(Vec.Normalize(axis)) : [];
|
||||
|
||||
static double[] RepresentativeNormal(IReadOnlyList<AssemblyFaceContactEvidence> contacts) =>
|
||||
contacts.Select(contact => contact.NormalA.Length >= 3 ? contact.NormalA : contact.NormalB)
|
||||
.FirstOrDefault(normal => normal.Length >= 3) is { Length: >= 3 } normal ? CanonicalDirection(Vec.Normalize(normal)) : [];
|
||||
|
||||
static double[] AverageCenters(IReadOnlyList<AssemblyFaceContactEvidence> contacts)
|
||||
{
|
||||
var centers = contacts.Select(contact => AverageVectors(contact.CenterA, contact.CenterB)).Where(center => center.Length >= 3).ToList();
|
||||
return centers.Count == 0
|
||||
? []
|
||||
: [centers.Average(center => center[0]), centers.Average(center => center[1]), centers.Average(center => center[2])];
|
||||
}
|
||||
|
||||
static double[] CanonicalDirection(double[] direction)
|
||||
{
|
||||
if (direction.Length < 3)
|
||||
return [];
|
||||
var first = direction.FirstOrDefault(value => Math.Abs(value) > 1e-6);
|
||||
return first < 0 ? Vec.Mul(direction, -1) : direction;
|
||||
}
|
||||
|
||||
static string VectorKey(double[] vector, double tolerance)
|
||||
{
|
||||
if (vector.Length < 3)
|
||||
return "none";
|
||||
tolerance = Math.Max(tolerance, 1e-6);
|
||||
return string.Join(",", vector.Take(3).Select(value => Math.Round(value / tolerance).ToString(System.Globalization.CultureInfo.InvariantCulture)));
|
||||
}
|
||||
|
||||
static HashSet<string> BuildPlanarProfilePairKeys(IReadOnlyList<AssemblyFaceContactEvidence> contacts)
|
||||
{
|
||||
var result = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (var group in contacts
|
||||
.Where(contact => contact.ContactKind.Equals("planar_face_contact_candidate", StringComparison.OrdinalIgnoreCase))
|
||||
.GroupBy(contact => ComponentPairKey(contact.ComponentA, contact.ComponentB), StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
var items = group.ToList();
|
||||
if (items.Count < 2)
|
||||
continue;
|
||||
|
||||
var normalFamilies = new List<double[]>();
|
||||
foreach (var contact in items)
|
||||
{
|
||||
var normal = contact.NormalA.Length >= 3 ? Vec.Normalize(contact.NormalA) : [];
|
||||
if (normal.Length < 3)
|
||||
continue;
|
||||
|
||||
var existing = normalFamilies.Any(family => Math.Abs(Vec.Dot(family, normal)) >= 0.92);
|
||||
if (!existing)
|
||||
normalFamilies.Add(normal);
|
||||
}
|
||||
|
||||
// Multi-direction planar contacts indicate prismatic/profile fits such as square shafts,
|
||||
// rectangular bosses, slots, or keyed interfaces. Same-direction multi-face groups are
|
||||
// kept as weaker profile candidates; ordinary single flat mounting contacts are excluded.
|
||||
if (normalFamilies.Count >= 2 || items.Count >= 3)
|
||||
result.Add(group.Key);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool ShouldExportFitLikeInterface(AssemblyFaceContactEvidence contact, IReadOnlySet<string> planarProfilePairKeys)
|
||||
{
|
||||
if (contact.ContactKind.Equals("cylindrical_coaxial_fit_candidate", StringComparison.OrdinalIgnoreCase))
|
||||
return true;
|
||||
|
||||
if (!contact.ContactKind.Equals("planar_face_contact_candidate", StringComparison.OrdinalIgnoreCase))
|
||||
return false;
|
||||
|
||||
return planarProfilePairKeys.Contains(ComponentPairKey(contact.ComponentA, contact.ComponentB));
|
||||
}
|
||||
|
||||
static ComponentImageRef BuildComponentImageRef(
|
||||
ComponentContextMember component,
|
||||
IReadOnlyDictionary<string, AssemblyComponentSummary> componentsById)
|
||||
{
|
||||
return new ComponentImageRef
|
||||
{
|
||||
ComponentId = component.ComponentId,
|
||||
InstanceName = component.InstanceName,
|
||||
DisplayName = component.DisplayName,
|
||||
ComponentPath = component.ComponentPath,
|
||||
BBoxMm = componentsById.TryGetValue(component.ComponentId, out var summary)
|
||||
? summary.BBoxMm
|
||||
: []
|
||||
};
|
||||
}
|
||||
|
||||
static ComponentImageRef BuildComponentImageRef(
|
||||
AssemblyComponentSummary? component,
|
||||
string instanceName,
|
||||
string displayName,
|
||||
string componentPath)
|
||||
{
|
||||
return new ComponentImageRef
|
||||
{
|
||||
ComponentId = component?.Id ?? SanitizeId(FirstNonEmpty(instanceName, displayName, Path.GetFileNameWithoutExtension(componentPath), "component")),
|
||||
InstanceName = component?.InstanceName ?? instanceName,
|
||||
DisplayName = component?.DisplayName ?? displayName,
|
||||
ComponentPath = component?.Path ?? componentPath,
|
||||
BBoxMm = component?.BBoxMm ?? []
|
||||
};
|
||||
}
|
||||
|
||||
static AssemblyComponentSummary? FindComponentSummary(
|
||||
IReadOnlyList<AssemblyComponentSummary> components,
|
||||
string instanceName,
|
||||
string componentPath)
|
||||
{
|
||||
return components.FirstOrDefault(component =>
|
||||
!string.IsNullOrWhiteSpace(instanceName) &&
|
||||
component.InstanceName.Equals(instanceName, StringComparison.OrdinalIgnoreCase) &&
|
||||
(string.IsNullOrWhiteSpace(componentPath) ||
|
||||
string.IsNullOrWhiteSpace(component.Path) ||
|
||||
component.Path.Equals(componentPath, StringComparison.OrdinalIgnoreCase)))
|
||||
?? components.FirstOrDefault(component =>
|
||||
!string.IsNullOrWhiteSpace(componentPath) &&
|
||||
!string.IsNullOrWhiteSpace(component.Path) &&
|
||||
component.Path.Equals(componentPath, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
static double ContactPriority(AssemblyFaceContactEvidence contact)
|
||||
{
|
||||
var text = $"{contact.ContactKind} {contact.MateRole} {contact.FaceRoleA} {contact.FaceRoleB}".ToLowerInvariant();
|
||||
if (text.Contains("cylindrical") || text.Contains("bearing") || text.Contains("hinge") || text.Contains("fit"))
|
||||
return 3.0;
|
||||
if (text.Contains("planar") || text.Contains("profile") || text.Contains("slot") || text.Contains("key"))
|
||||
return 1.0;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
static string ComponentPairKey(string a, string b) =>
|
||||
string.Compare(a, b, StringComparison.OrdinalIgnoreCase) <= 0
|
||||
? $"{a}||{b}"
|
||||
: $"{b}||{a}";
|
||||
|
||||
static double[] ChooseInterfaceHighlightDirection(
|
||||
AssemblyFaceContactEvidence contact,
|
||||
IReadOnlyList<AssemblyComponentSummary> components)
|
||||
{
|
||||
var center = AverageVectors(contact.CenterA, contact.CenterB);
|
||||
var assemblyBox = UnionBoxes(components.Select(component => component.BBoxMm));
|
||||
var outward = Array.Empty<double>();
|
||||
if (center.Length >= 3 && assemblyBox.Length >= 6)
|
||||
{
|
||||
var away = Vec.Sub(center, BoxCenter(assemblyBox));
|
||||
if (Vec.Norm(away) > 1.0)
|
||||
outward = Vec.Normalize(away);
|
||||
}
|
||||
|
||||
var axis = contact.AxisA.Length >= 3 ? Vec.Normalize(contact.AxisA) :
|
||||
contact.AxisB.Length >= 3 ? Vec.Normalize(contact.AxisB) : [];
|
||||
var normal = contact.NormalA.Length >= 3 ? contact.NormalA : contact.NormalB;
|
||||
normal = normal.Length >= 3 ? Vec.Normalize(normal) : [];
|
||||
var isCylindrical = contact.ContactKind.Contains("cylindrical", StringComparison.OrdinalIgnoreCase);
|
||||
var componentA = FindComponentSummary(components, contact.ComponentA, contact.ComponentPathA);
|
||||
var componentB = FindComponentSummary(components, contact.ComponentB, contact.ComponentPathB);
|
||||
var boxA = componentA?.BBoxMm is { Length: >= 6 } ? componentA.BBoxMm : contact.BBoxA;
|
||||
var boxB = componentB?.BBoxMm is { Length: >= 6 } ? componentB.BBoxMm : contact.BBoxB;
|
||||
|
||||
return InterfaceObliqueCandidateDirections()
|
||||
.OrderByDescending(direction => ScoreInterfaceViewDirection(direction, boxA, boxB, outward, axis, normal, isCylindrical))
|
||||
.First();
|
||||
}
|
||||
|
||||
static double ScoreInterfaceViewDirection(double[] direction, double[] boxA, double[] boxB, double[] outward, double[] axis, double[] normal, bool isCylindrical)
|
||||
{
|
||||
var visibilityScore = ScorePairProjectedVisibility(boxA, boxB, direction);
|
||||
|
||||
var geometryPreference = 0.0;
|
||||
if (outward.Length >= 3)
|
||||
geometryPreference += 0.8 * Math.Max(0.0, Vec.Dot(direction, outward));
|
||||
|
||||
if (isCylindrical && axis.Length >= 3)
|
||||
geometryPreference += 0.7 * (1.0 - Math.Abs(Vec.Dot(direction, axis)));
|
||||
|
||||
if (!isCylindrical && normal.Length >= 3)
|
||||
geometryPreference += 0.7 * Math.Abs(Vec.Dot(direction, normal));
|
||||
|
||||
return visibilityScore * (1.0 + geometryPreference);
|
||||
}
|
||||
|
||||
static double ScorePairProjectedVisibility(double[] boxA, double[] boxB, double[] direction)
|
||||
{
|
||||
if (boxA.Length < 6 || boxB.Length < 6)
|
||||
return 1.0;
|
||||
|
||||
var projectionA = ProjectBoxForInterface(boxA, direction);
|
||||
var projectionB = ProjectBoxForInterface(boxB, direction);
|
||||
var areaA = projectionA.Area;
|
||||
var areaB = projectionB.Area;
|
||||
var overlap = OverlapArea(projectionA, projectionB);
|
||||
var unionArea = Math.Max(1.0, areaA + areaB - overlap);
|
||||
var smallerArea = Math.Max(1.0, Math.Min(areaA, areaB));
|
||||
var largerArea = Math.Max(smallerArea, Math.Max(areaA, areaB));
|
||||
var overlapRatio = Math.Min(1.0, overlap / smallerArea);
|
||||
var balance = smallerArea / largerArea;
|
||||
|
||||
// Contact faces are usually hidden; favor views where both components expose
|
||||
// enough surrounding exterior area instead of one box covering the other.
|
||||
return unionArea * (1.0 - overlapRatio * 0.85) * (0.75 + balance * 0.25);
|
||||
}
|
||||
|
||||
static InterfaceProjectionRect ProjectBoxForInterface(double[] box, double[] direction)
|
||||
{
|
||||
var d = Vec.Normalize(direction);
|
||||
var reference = Math.Abs(Vec.Dot(d, [0.0, 1.0, 0.0])) > 0.92
|
||||
? new[] { 0.0, 0.0, 1.0 }
|
||||
: [0.0, 1.0, 0.0];
|
||||
var u = Vec.Normalize(Vec.Cross(reference, d));
|
||||
var v = Vec.Normalize(Vec.Cross(d, u));
|
||||
var corners = BoxCorners(box);
|
||||
var uRange = ProjectionRange(corners, u);
|
||||
var vRange = ProjectionRange(corners, v);
|
||||
return new InterfaceProjectionRect(uRange.Min, uRange.Max, vRange.Min, vRange.Max);
|
||||
}
|
||||
|
||||
static double OverlapArea(InterfaceProjectionRect a, InterfaceProjectionRect b)
|
||||
{
|
||||
var u = Math.Max(0.0, Math.Min(a.UMax, b.UMax) - Math.Max(a.UMin, b.UMin));
|
||||
var v = Math.Max(0.0, Math.Min(a.VMax, b.VMax) - Math.Max(a.VMin, b.VMin));
|
||||
return u * v;
|
||||
}
|
||||
|
||||
static List<double[]> BoxCorners(double[] box) =>
|
||||
[
|
||||
[box[0], box[1], box[2]],
|
||||
[box[0], box[1], box[5]],
|
||||
[box[0], box[4], box[2]],
|
||||
[box[0], box[4], box[5]],
|
||||
[box[3], box[1], box[2]],
|
||||
[box[3], box[1], box[5]],
|
||||
[box[3], box[4], box[2]],
|
||||
[box[3], box[4], box[5]]
|
||||
];
|
||||
|
||||
static (double Min, double Max) ProjectionRange(IReadOnlyList<double[]> points, double[] axis)
|
||||
{
|
||||
var values = points.Select(point => Vec.Dot(point, axis)).ToList();
|
||||
return (values.Min(), values.Max());
|
||||
}
|
||||
|
||||
static List<double[]> InterfaceObliqueCandidateDirections() =>
|
||||
[
|
||||
Vec.Normalize([1.0, 1.0, 1.0]),
|
||||
Vec.Normalize([1.0, 1.0, -1.0]),
|
||||
Vec.Normalize([1.0, -1.0, 1.0]),
|
||||
Vec.Normalize([1.0, -1.0, -1.0]),
|
||||
Vec.Normalize([-1.0, 1.0, 1.0]),
|
||||
Vec.Normalize([-1.0, 1.0, -1.0]),
|
||||
Vec.Normalize([-1.0, -1.0, 1.0]),
|
||||
Vec.Normalize([-1.0, -1.0, -1.0])
|
||||
];
|
||||
|
||||
static double[] AverageVectors(double[] a, double[] b)
|
||||
{
|
||||
if (a.Length < 3 && b.Length < 3)
|
||||
return [];
|
||||
if (a.Length < 3)
|
||||
return b.Take(3).ToArray();
|
||||
if (b.Length < 3)
|
||||
return a.Take(3).ToArray();
|
||||
return [(a[0] + b[0]) / 2.0, (a[1] + b[1]) / 2.0, (a[2] + b[2]) / 2.0];
|
||||
}
|
||||
|
||||
static bool ContainsAny(string value, params string[] tokens) =>
|
||||
tokens.Any(token => value.Contains(token, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
static double[] ChooseComponentHighlightDirection(
|
||||
AssemblyComponentSummary component,
|
||||
IReadOnlyList<AssemblyComponentSummary> allComponents)
|
||||
{
|
||||
if (component.BBoxMm.Length < 6)
|
||||
return [1.0, 1.0, 1.0];
|
||||
|
||||
var assemblyBox = UnionBoxes(allComponents.Select(item => item.BBoxMm));
|
||||
if (assemblyBox.Length < 6)
|
||||
return [1.0, 1.0, 1.0];
|
||||
|
||||
var componentCenter = BoxCenter(component.BBoxMm);
|
||||
var assemblyCenter = BoxCenter(assemblyBox);
|
||||
var delta = componentCenter.Zip(assemblyCenter, (a, b) => a - b).ToArray();
|
||||
|
||||
double Axis(double value, int index)
|
||||
{
|
||||
if (Math.Abs(value) > 1.0)
|
||||
return Math.Sign(value);
|
||||
|
||||
var componentSpan = Math.Abs(component.BBoxMm[index + 3] - component.BBoxMm[index]);
|
||||
var assemblySpan = Math.Abs(assemblyBox[index + 3] - assemblyBox[index]);
|
||||
return componentSpan >= assemblySpan * 0.45 ? 1.0 : (index == 1 ? 1.0 : -1.0);
|
||||
}
|
||||
|
||||
return Vec.Normalize([Axis(delta[0], 0), Axis(delta[1], 1), Axis(delta[2], 2)]);
|
||||
}
|
||||
|
||||
static double[] UnionBoxes(IEnumerable<double[]> boxes)
|
||||
{
|
||||
var valid = boxes.Where(box => box.Length >= 6).ToList();
|
||||
if (valid.Count == 0)
|
||||
return [];
|
||||
|
||||
return
|
||||
[
|
||||
valid.Min(box => box[0]),
|
||||
valid.Min(box => box[1]),
|
||||
valid.Min(box => box[2]),
|
||||
valid.Max(box => box[3]),
|
||||
valid.Max(box => box[4]),
|
||||
valid.Max(box => box[5])
|
||||
];
|
||||
}
|
||||
|
||||
static double[] BoxCenter(double[] box) =>
|
||||
box.Length >= 6
|
||||
? [(box[0] + box[3]) / 2.0, (box[1] + box[4]) / 2.0, (box[2] + box[5]) / 2.0]
|
||||
: [];
|
||||
|
||||
static string SanitizeId(string value)
|
||||
{
|
||||
var chars = value.Select(ch => char.IsLetterOrDigit(ch) ? ch : '_').ToArray();
|
||||
return new string(chars).Trim('_');
|
||||
}
|
||||
|
||||
static string FirstNonEmpty(params string[] values) =>
|
||||
values.FirstOrDefault(value => !string.IsNullOrWhiteSpace(value)) ?? "";
|
||||
}
|
||||
|
||||
readonly record struct InterfaceProjectionRect(double UMin, double UMax, double VMin, double VMax)
|
||||
{
|
||||
public double Area => Math.Max(1.0, (UMax - UMin) * (VMax - VMin));
|
||||
}
|
||||
|
||||
sealed class PhysicalInterfaceGroup
|
||||
{
|
||||
public string BaseKey { get; set; } = "";
|
||||
public string Id { get; set; } = "";
|
||||
public List<AssemblyFaceContactEvidence> Contacts { get; set; } = [];
|
||||
public List<string> FaceARefs { get; set; } = [];
|
||||
public List<string> FaceBRefs { get; set; } = [];
|
||||
public List<int> FaceAIndices { get; set; } = [];
|
||||
public List<int> FaceBIndices { get; set; } = [];
|
||||
public List<Face2> RuntimeFaces { get; set; } = [];
|
||||
public double AnalysisPriority { get; set; }
|
||||
public string ConfidenceTier { get; set; } = "";
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,505 @@
|
||||
static class PartModelProcessing
|
||||
{
|
||||
public const string DirectPartBrepSource = "part_brep_direct";
|
||||
|
||||
public static List<ComponentHighlightImageRequest> BuildComponentHighlightImageRequests(SectionBrepReport report) => [];
|
||||
|
||||
public static List<FeatureHighlightImageRequest> BuildFeatureHighlightImageRequests(SectionBrepReport report)
|
||||
{
|
||||
var result = new List<FeatureHighlightImageRequest>();
|
||||
var component = report.AssemblyComponents
|
||||
.FirstOrDefault(c => c.ReviewScope.Equals("part_design_required", StringComparison.OrdinalIgnoreCase))
|
||||
?? report.AssemblyComponents.FirstOrDefault();
|
||||
if (component == null)
|
||||
return result;
|
||||
|
||||
var facesByRef = report.AssemblyFaces
|
||||
.GroupBy(FaceRef, StringComparer.OrdinalIgnoreCase)
|
||||
.ToDictionary(g => g.Key, g => g.First(), StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
foreach (var feature in report.FeatureGraph.Features
|
||||
.Where(f => f.FaceRefs.Count > 0)
|
||||
.Where(f => SameComponent(f, component))
|
||||
.OrderBy(f => FeatureHighlightPriority(f.Type))
|
||||
.ThenBy(f => f.Id, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
var targetFaces = feature.FaceRefs
|
||||
.Select(faceRef => facesByRef.TryGetValue(faceRef, out var face) ? face : null)
|
||||
.OfType<AssemblyFaceEvidence>()
|
||||
.ToList();
|
||||
if (targetFaces.Count == 0)
|
||||
continue;
|
||||
|
||||
var viewChoice = ChooseBestObliqueFeatureView(feature, targetFaces, report.AssemblyFaces);
|
||||
result.Add(new FeatureHighlightImageRequest
|
||||
{
|
||||
PlanId = $"feature_highlight_{SanitizeId(feature.Id)}",
|
||||
ComponentId = component.Id,
|
||||
InstanceName = component.InstanceName,
|
||||
DisplayName = component.DisplayName,
|
||||
ComponentPath = component.Path,
|
||||
FeatureId = feature.Id,
|
||||
FeatureType = feature.Type,
|
||||
FaceRefs = feature.FaceRefs.Distinct(StringComparer.OrdinalIgnoreCase).ToList(),
|
||||
Views = [viewChoice.ViewName],
|
||||
PreferredDirectionMm = Vec.Round(viewChoice.Direction),
|
||||
BlockingFaceRefs = viewChoice.BlockingFaceRefs,
|
||||
SelectionBasis = "feature_graph_face_refs_grouped_before_image_export"
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<ComponentContextImageRequest> BuildComponentContextImageRequests(SectionBrepReport report) => [];
|
||||
|
||||
public static AutoSectionImagePlan BuildAxisSectionPlan(SectionBrepReport report)
|
||||
{
|
||||
var plan = new AutoSectionImagePlan
|
||||
{
|
||||
MaxRequests = 1
|
||||
};
|
||||
|
||||
var axisFace = report.AssemblyFaces
|
||||
.Where(face => face.FaceKind.Equals("cylinder", StringComparison.OrdinalIgnoreCase))
|
||||
.Where(face => face.Axis.Length >= 3 && face.AxisPointMm.Length >= 3)
|
||||
.OrderByDescending(face => face.AreaMm2)
|
||||
.ThenByDescending(face => face.RadiusMm)
|
||||
.FirstOrDefault();
|
||||
if (axisFace == null)
|
||||
return plan;
|
||||
|
||||
var containedAxis = Vec.Normalize(axisFace.Axis);
|
||||
var coaxialFaces = report.AssemblyFaces
|
||||
.Where(face => face.FaceKind.Equals("cylinder", StringComparison.OrdinalIgnoreCase))
|
||||
.Where(face => face.Axis.Length >= 3 && face.AxisPointMm.Length >= 3)
|
||||
.Where(face => Math.Abs(Vec.Dot(Vec.Normalize(face.Axis), containedAxis)) >= 0.95)
|
||||
.ToList();
|
||||
if (!HasInternalRotationalStructure(coaxialFaces))
|
||||
return plan;
|
||||
|
||||
var target = string.IsNullOrWhiteSpace(axisFace.ComponentDisplayName)
|
||||
? axisFace.ComponentName
|
||||
: axisFace.ComponentDisplayName;
|
||||
var planeCandidates = ChooseSectionPlaneKeys(containedAxis);
|
||||
for (var i = 0; i < Math.Min(plan.MaxRequests, planeCandidates.Count); i++)
|
||||
{
|
||||
var candidate = planeCandidates[i];
|
||||
plan.Requests.Add(new AutoSectionImageRequest
|
||||
{
|
||||
Request = $"part_axis_center_section_{i + 1}",
|
||||
Rule = "For SLDPRT rotational parts with internal/coaxial structure, create a section plane through the main cylindrical axis.",
|
||||
Target = target,
|
||||
Reason = "Part input has no assembly components to hide or highlight; section evidence is generated directly from the opened part body.",
|
||||
PlaneKey = candidate.PlaneKey,
|
||||
OffsetMm = 0,
|
||||
OriginMm = Vec.Round(axisFace.AxisPointMm),
|
||||
PreferredNormalMm = Vec.Round(candidate.Normal),
|
||||
PreferredContainedAxisMm = Vec.Round(containedAxis),
|
||||
SourceRefs = [$"{axisFace.ComponentName}:face#{axisFace.FaceIndex}"]
|
||||
});
|
||||
}
|
||||
|
||||
return plan;
|
||||
}
|
||||
|
||||
public static List<string> BuildSectionViewRequests(SectionBrepReport report)
|
||||
{
|
||||
return report.SectionImagePlan.Requests
|
||||
.Where(request => !string.IsNullOrWhiteSpace(request.PlaneKey))
|
||||
.Take(2)
|
||||
.Select(request =>
|
||||
$"{request.PlaneKey}:{request.Request}|target={SanitizeMetadata(request.Target)};reason={SanitizeMetadata(request.Reason)}")
|
||||
.ToList();
|
||||
}
|
||||
|
||||
static bool HasInternalRotationalStructure(IReadOnlyList<AssemblyFaceEvidence> coaxialFaces)
|
||||
{
|
||||
if (coaxialFaces.Count < 2)
|
||||
return false;
|
||||
|
||||
var radiusLayers = coaxialFaces
|
||||
.Where(face => face.RadiusMm > 0)
|
||||
.Select(face => Math.Round(face.RadiusMm, 1))
|
||||
.Distinct()
|
||||
.Count();
|
||||
if (radiusLayers >= 2)
|
||||
return true;
|
||||
|
||||
return coaxialFaces.Any(face =>
|
||||
face.FunctionalRole.Contains("hole", StringComparison.OrdinalIgnoreCase) ||
|
||||
face.FunctionalRole.Contains("bore", StringComparison.OrdinalIgnoreCase) ||
|
||||
face.SurfaceProcessRole.Contains("hole", StringComparison.OrdinalIgnoreCase) ||
|
||||
face.SurfaceProcessRole.Contains("bore", StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
static List<(string PlaneKey, double[] Normal)> ChooseSectionPlaneKeys(double[] containedAxis)
|
||||
{
|
||||
var candidates = new List<(string PlaneKey, double[] Normal)>
|
||||
{
|
||||
("front", [0.0, 0.0, 1.0]),
|
||||
("top", [0.0, 1.0, 0.0]),
|
||||
("right", [1.0, 0.0, 0.0])
|
||||
};
|
||||
|
||||
return candidates
|
||||
.OrderBy(candidate => Math.Abs(Vec.Dot(containedAxis, candidate.Normal)))
|
||||
.ThenBy(candidate => candidate.PlaneKey, StringComparer.OrdinalIgnoreCase)
|
||||
.Take(2)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
static string SanitizeMetadata(string value) =>
|
||||
(value ?? "").Replace(';', ',').Replace('|', '/').Replace('\r', ' ').Replace('\n', ' ').Trim();
|
||||
|
||||
static bool SameComponent(MechanicalFeature feature, AssemblyComponentSummary component)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(feature.ComponentPath) &&
|
||||
!string.IsNullOrWhiteSpace(component.Path) &&
|
||||
feature.ComponentPath.Equals(component.Path, StringComparison.OrdinalIgnoreCase))
|
||||
return true;
|
||||
|
||||
return feature.ComponentName.Equals(component.InstanceName, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
static int FeatureHighlightPriority(string featureType)
|
||||
{
|
||||
if (featureType.Contains("unknown", StringComparison.OrdinalIgnoreCase) ||
|
||||
featureType.Contains("complex", StringComparison.OrdinalIgnoreCase))
|
||||
return 0;
|
||||
if (featureType.Contains("hole", StringComparison.OrdinalIgnoreCase))
|
||||
return 1;
|
||||
if (featureType.Contains("cylindrical", StringComparison.OrdinalIgnoreCase))
|
||||
return 2;
|
||||
if (featureType.Contains("planar", StringComparison.OrdinalIgnoreCase))
|
||||
return 3;
|
||||
return 4;
|
||||
}
|
||||
|
||||
static (string ViewName, double[] Direction, List<string> BlockingFaceRefs) ChooseBestObliqueFeatureView(
|
||||
MechanicalFeature feature,
|
||||
IReadOnlyList<AssemblyFaceEvidence> targetFaces,
|
||||
IReadOnlyList<AssemblyFaceEvidence> allFaces)
|
||||
{
|
||||
var targetBox = UnionBoxes(targetFaces.Select(f => f.BBoxMm));
|
||||
if (targetBox.Length < 6)
|
||||
return ("isometric", [1.0, 1.0, 1.0], []);
|
||||
|
||||
var targetRefs = feature.FaceRefs.ToHashSet(StringComparer.OrdinalIgnoreCase);
|
||||
var others = allFaces
|
||||
.Where(face => !targetRefs.Contains(FaceRef(face)))
|
||||
.Where(face => face.BBoxMm.Length >= 6)
|
||||
.ToList();
|
||||
|
||||
var isPlanarTarget = IsPlanarFeatureTarget(feature, targetFaces);
|
||||
var preferredViewSide = DeterminePreferredViewSide(feature, targetFaces, allFaces, targetBox);
|
||||
var candidates = BuildObliqueCandidateDirections(false);
|
||||
candidates = EnforcePreferredViewSide(candidates, preferredViewSide, isPlanarTarget);
|
||||
|
||||
var projectedTargetAreas = candidates
|
||||
.Select(direction => ProjectBox(targetBox, direction).Area)
|
||||
.ToList();
|
||||
var maxTargetArea = Math.Max(1.0, projectedTargetAreas.Max());
|
||||
|
||||
var bestScore = double.MaxValue;
|
||||
var bestDirection = candidates[0];
|
||||
var bestBlocking = new List<string>();
|
||||
|
||||
for (var i = 0; i < candidates.Count; i++)
|
||||
{
|
||||
var direction = candidates[i];
|
||||
var targetProjection = ProjectBox(targetBox, direction);
|
||||
var blockers = new List<(string Ref, double Penalty)>();
|
||||
var score = (maxTargetArea - targetProjection.Area) / maxTargetArea * (isPlanarTarget ? 0.08 : 0.35);
|
||||
var absDirection = direction.Select(Math.Abs).ToArray();
|
||||
var maxComponent = Math.Max(absDirection[0], Math.Max(absDirection[1], absDirection[2]));
|
||||
var minComponent = Math.Min(absDirection[0], Math.Min(absDirection[1], absDirection[2]));
|
||||
score += (maxComponent - minComponent) / Math.Max(maxComponent, 0.001) * (isPlanarTarget ? 0.04 : 0.25);
|
||||
score += PreferredViewSidePenalty(direction, preferredViewSide, isPlanarTarget);
|
||||
score += StableNonPlanarAzimuthPenalty(feature, targetFaces, direction, preferredViewSide, isPlanarTarget);
|
||||
|
||||
foreach (var other in others)
|
||||
{
|
||||
var otherProjection = ProjectBox(other.BBoxMm, direction);
|
||||
var overlap = OverlapArea(targetProjection, otherProjection);
|
||||
if (overlap <= 0.001)
|
||||
continue;
|
||||
|
||||
var inFrontGap = otherProjection.MaxDepth - targetProjection.MinDepth;
|
||||
if (inFrontGap <= 0)
|
||||
continue;
|
||||
|
||||
var penalty = overlap / Math.Max(targetProjection.Area, 1.0) * (1.0 + Math.Min(inFrontGap, 100.0) / 200.0);
|
||||
score += penalty;
|
||||
blockers.Add((FaceRef(other), penalty));
|
||||
}
|
||||
|
||||
if (score < bestScore)
|
||||
{
|
||||
bestScore = score;
|
||||
bestDirection = direction;
|
||||
bestBlocking = blockers
|
||||
.OrderByDescending(item => item.Penalty)
|
||||
.Take(8)
|
||||
.Select(item => item.Ref)
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
return (ObliqueDirectionName(bestDirection), bestDirection, bestBlocking);
|
||||
}
|
||||
|
||||
static bool IsPlanarFeatureTarget(MechanicalFeature feature, IReadOnlyList<AssemblyFaceEvidence> targetFaces)
|
||||
{
|
||||
if (feature.Type.Contains("planar", StringComparison.OrdinalIgnoreCase))
|
||||
return true;
|
||||
|
||||
return targetFaces.Count > 0 &&
|
||||
targetFaces.All(face => face.FaceKind.Equals("plane", StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
static double[] DeterminePreferredViewSide(
|
||||
MechanicalFeature feature,
|
||||
IReadOnlyList<AssemblyFaceEvidence> targetFaces,
|
||||
IReadOnlyList<AssemblyFaceEvidence> allFaces,
|
||||
double[] targetBox)
|
||||
{
|
||||
var planeNormal = WeightedAverageNormal(targetFaces
|
||||
.Where(face => face.FaceKind.Equals("plane", StringComparison.OrdinalIgnoreCase))
|
||||
.Where(face => face.Normal.Length >= 3));
|
||||
if (planeNormal.Length >= 3)
|
||||
return planeNormal;
|
||||
|
||||
var componentFaces = allFaces
|
||||
.Where(face => face.ComponentName.Equals(feature.ComponentName, StringComparison.OrdinalIgnoreCase))
|
||||
.Where(face => face.BBoxMm.Length >= 6)
|
||||
.ToList();
|
||||
if (componentFaces.Count == 0)
|
||||
componentFaces = allFaces.Where(face => face.BBoxMm.Length >= 6).ToList();
|
||||
|
||||
var modelBox = UnionBoxes(componentFaces.Select(face => face.BBoxMm));
|
||||
var targetCenter = BoxCenter(targetBox);
|
||||
var modelCenter = BoxCenter(modelBox);
|
||||
if (targetCenter.Length < 3 || modelCenter.Length < 3 || modelBox.Length < 6)
|
||||
return [];
|
||||
|
||||
var verticalOffset = targetCenter[1] - modelCenter[1];
|
||||
if (Math.Abs(verticalOffset) >= 0.001)
|
||||
return verticalOffset > 0
|
||||
? [0.0, 1.0, 0.0]
|
||||
: [0.0, -1.0, 0.0];
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
static double[] WeightedAverageNormal(IEnumerable<AssemblyFaceEvidence> faces)
|
||||
{
|
||||
var sum = new[] { 0.0, 0.0, 0.0 };
|
||||
var totalWeight = 0.0;
|
||||
foreach (var face in faces)
|
||||
{
|
||||
var normal = Vec.Normalize(face.Normal);
|
||||
if (normal.Length < 3)
|
||||
continue;
|
||||
|
||||
var weight = Math.Max(face.AreaMm2, 1.0);
|
||||
sum = Vec.Add(sum, Vec.Mul(normal, weight));
|
||||
totalWeight += weight;
|
||||
}
|
||||
|
||||
if (totalWeight <= 0.0 || Vec.Norm(sum) < 1e-6)
|
||||
return [];
|
||||
|
||||
return Vec.Normalize(sum);
|
||||
}
|
||||
|
||||
static List<double[]> EnforcePreferredViewSide(List<double[]> candidates, double[] preferredViewSide, bool preferSteeperPlanarOblique)
|
||||
{
|
||||
if (preferredViewSide.Length < 3)
|
||||
return candidates;
|
||||
|
||||
var preferred = Vec.Normalize(preferredViewSide);
|
||||
var minimumAlignment = preferSteeperPlanarOblique ? 0.30 : 0.7;
|
||||
var maximumAlignment = preferSteeperPlanarOblique ? 0.78 : 1.0;
|
||||
var filtered = candidates
|
||||
.Where(direction =>
|
||||
{
|
||||
var alignment = Vec.Dot(Vec.Normalize(direction), preferred);
|
||||
return alignment >= minimumAlignment && alignment <= maximumAlignment;
|
||||
})
|
||||
.ToList();
|
||||
|
||||
if (filtered.Count == 0 && preferSteeperPlanarOblique)
|
||||
{
|
||||
filtered = candidates
|
||||
.Where(direction => Vec.Dot(Vec.Normalize(direction), preferred) >= minimumAlignment)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
return filtered.Count > 0 ? filtered : candidates;
|
||||
}
|
||||
|
||||
static double PreferredViewSidePenalty(double[] direction, double[] preferredViewSide, bool preferSteeperPlanarOblique)
|
||||
{
|
||||
if (preferredViewSide.Length < 3)
|
||||
return 0.0;
|
||||
|
||||
var alignment = Vec.Dot(Vec.Normalize(direction), Vec.Normalize(preferredViewSide));
|
||||
if (preferSteeperPlanarOblique)
|
||||
{
|
||||
const double targetPlanarAlignment = 0.45;
|
||||
return Math.Abs(alignment - targetPlanarAlignment) * 0.55;
|
||||
}
|
||||
|
||||
return (1.0 - alignment) * 0.55;
|
||||
}
|
||||
|
||||
static double StableNonPlanarAzimuthPenalty(
|
||||
MechanicalFeature feature,
|
||||
IReadOnlyList<AssemblyFaceEvidence> targetFaces,
|
||||
double[] direction,
|
||||
double[] preferredViewSide,
|
||||
bool isPlanarTarget)
|
||||
{
|
||||
if (isPlanarTarget || preferredViewSide.Length < 3)
|
||||
return 0.0;
|
||||
|
||||
var hasCurvedOrUnknownTarget = targetFaces.Any(face =>
|
||||
face.FaceKind.Equals("cylinder", StringComparison.OrdinalIgnoreCase) ||
|
||||
face.FaceKind.Equals("cone", StringComparison.OrdinalIgnoreCase) ||
|
||||
face.FaceKind.Equals("other", StringComparison.OrdinalIgnoreCase));
|
||||
if (!hasCurvedOrUnknownTarget)
|
||||
return 0.0;
|
||||
|
||||
var preferred = Vec.Normalize(preferredViewSide);
|
||||
if (preferred.Length < 3 || Math.Abs(preferred[1]) < 0.5)
|
||||
return 0.0;
|
||||
|
||||
// When curved/unknown faces only tell us "upper/lower", X/Z is otherwise decided
|
||||
// by small bbox-score differences. Keep a stable oblique quadrant for direct part
|
||||
// images so adjacent main-axis cylindrical features are viewed consistently.
|
||||
var stableOblique = Vec.Normalize([1.0, preferred[1] >= 0 ? 2.0 : -2.0, -1.0]);
|
||||
var alignment = Vec.Dot(Vec.Normalize(direction), stableOblique);
|
||||
var weight = feature.Type.Contains("main_axis_cylindrical", StringComparison.OrdinalIgnoreCase)
|
||||
? 0.35
|
||||
: 0.18;
|
||||
|
||||
return (1.0 - alignment) * weight;
|
||||
}
|
||||
|
||||
static double[] ProjectOntoPlane(double[] vector, double[] planeNormal)
|
||||
{
|
||||
var normal = Vec.Normalize(planeNormal);
|
||||
var v = Vec.Normalize(vector);
|
||||
if (normal.Length < 3 || v.Length < 3)
|
||||
return [];
|
||||
|
||||
return Vec.Normalize(Vec.Sub(v, Vec.Mul(normal, Vec.Dot(v, normal))));
|
||||
}
|
||||
|
||||
static string ObliqueDirectionName(double[] direction)
|
||||
{
|
||||
static string Sign(double value, string axis) => value >= 0 ? $"{axis}p" : $"{axis}n";
|
||||
var ax = Math.Abs(direction.ElementAtOrDefault(0));
|
||||
var ay = Math.Abs(direction.ElementAtOrDefault(1));
|
||||
var az = Math.Abs(direction.ElementAtOrDefault(2));
|
||||
var min = Math.Max(0.001, Math.Min(ax, Math.Min(ay, az)));
|
||||
var wx = Math.Max(1, (int)Math.Round(ax / min));
|
||||
var wy = Math.Max(1, (int)Math.Round(ay / min));
|
||||
var wz = Math.Max(1, (int)Math.Round(az / min));
|
||||
var signName = $"oblique_{Sign(direction.ElementAtOrDefault(0), "x")}_{Sign(direction.ElementAtOrDefault(1), "y")}_{Sign(direction.ElementAtOrDefault(2), "z")}";
|
||||
return wx == 1 && wy == 1 && wz == 1
|
||||
? signName
|
||||
: $"{signName}_x{wx}_y{wy}_z{wz}";
|
||||
}
|
||||
|
||||
static List<double[]> BuildObliqueCandidateDirections(bool includeSteepPlanarObliques)
|
||||
{
|
||||
var signs = new[] { -1.0, 1.0 };
|
||||
var result = new List<double[]>();
|
||||
|
||||
foreach (var sx in signs)
|
||||
foreach (var sy in signs)
|
||||
foreach (var sz in signs)
|
||||
{
|
||||
result.Add(Vec.Normalize([sx, sy, sz]));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static double[] UnionBoxes(IEnumerable<double[]> boxes)
|
||||
{
|
||||
var valid = boxes.Where(box => box.Length >= 6).ToList();
|
||||
if (valid.Count == 0)
|
||||
return [];
|
||||
|
||||
return
|
||||
[
|
||||
valid.Min(box => box[0]),
|
||||
valid.Min(box => box[1]),
|
||||
valid.Min(box => box[2]),
|
||||
valid.Max(box => box[3]),
|
||||
valid.Max(box => box[4]),
|
||||
valid.Max(box => box[5])
|
||||
];
|
||||
}
|
||||
|
||||
static double[] BoxCenter(double[] box) =>
|
||||
box.Length >= 6
|
||||
? [(box[0] + box[3]) / 2.0, (box[1] + box[4]) / 2.0, (box[2] + box[5]) / 2.0]
|
||||
: [];
|
||||
|
||||
static ProjectedBox ProjectBox(double[] box, double[] viewDirection)
|
||||
{
|
||||
var d = Vec.Normalize(viewDirection);
|
||||
var up = Math.Abs(Vec.Dot(d, [0.0, 1.0, 0.0])) > 0.92 ? new[] { 0.0, 0.0, 1.0 } : new[] { 0.0, 1.0, 0.0 };
|
||||
var u = Vec.Normalize(Vec.Cross(up, d));
|
||||
var v = Vec.Normalize(Vec.Cross(d, u));
|
||||
|
||||
var corners = BoxCorners(box);
|
||||
var uValues = corners.Select(p => Vec.Dot(p, u)).ToList();
|
||||
var vValues = corners.Select(p => Vec.Dot(p, v)).ToList();
|
||||
var dValues = corners.Select(p => Vec.Dot(p, d)).ToList();
|
||||
|
||||
return new ProjectedBox(
|
||||
uValues.Min(),
|
||||
uValues.Max(),
|
||||
vValues.Min(),
|
||||
vValues.Max(),
|
||||
dValues.Min(),
|
||||
dValues.Max());
|
||||
}
|
||||
|
||||
static List<double[]> BoxCorners(double[] box) =>
|
||||
[
|
||||
[box[0], box[1], box[2]],
|
||||
[box[0], box[1], box[5]],
|
||||
[box[0], box[4], box[2]],
|
||||
[box[0], box[4], box[5]],
|
||||
[box[3], box[1], box[2]],
|
||||
[box[3], box[1], box[5]],
|
||||
[box[3], box[4], box[2]],
|
||||
[box[3], box[4], box[5]]
|
||||
];
|
||||
|
||||
static double OverlapArea(ProjectedBox a, ProjectedBox b)
|
||||
{
|
||||
var width = Math.Max(0.0, Math.Min(a.MaxU, b.MaxU) - Math.Max(a.MinU, b.MinU));
|
||||
var height = Math.Max(0.0, Math.Min(a.MaxV, b.MaxV) - Math.Max(a.MinV, b.MinV));
|
||||
return width * height;
|
||||
}
|
||||
|
||||
static string FaceRef(AssemblyFaceEvidence face) => $"{face.ComponentName}:face#{face.FaceIndex}";
|
||||
|
||||
static string SanitizeId(string value)
|
||||
{
|
||||
var chars = value.Select(ch => char.IsLetterOrDigit(ch) ? ch : '_').ToArray();
|
||||
return new string(chars).Trim('_');
|
||||
}
|
||||
}
|
||||
|
||||
sealed record ProjectedBox(double MinU, double MaxU, double MinV, double MaxV, double MinDepth, double MaxDepth)
|
||||
{
|
||||
public double Area => Math.Max(0.0, MaxU - MinU) * Math.Max(0.0, MaxV - MinV);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,108 @@
|
||||
# SectionBrepExtractor
|
||||
|
||||
Temporary extractor for true section B-rep evidence.
|
||||
|
||||
Goal:
|
||||
|
||||
1. Use a chosen section plane.
|
||||
2. Intersect SolidWorks bodies with that plane using official API hooks.
|
||||
3. Convert the section result into a 2D B-rep-style evidence object: faces, edges, loops, and component provenance.
|
||||
|
||||
This is the layer that will eventually compare a textbook section image's lines against a model's section B-rep.
|
||||
|
||||
Run:
|
||||
|
||||
```powershell
|
||||
dotnet run --project tools\model-diagnostics\SectionBrepExtractor\SectionBrepExtractor.csproj -c Release -- "D:\path\model.SLDASM"
|
||||
```
|
||||
|
||||
Optionally export model-view JPG images during the same run:
|
||||
|
||||
```powershell
|
||||
dotnet run --project tools\model-diagnostics\SectionBrepExtractor\SectionBrepExtractor.csproj -c Release -- "D:\path\model.SLDASM" --output-dir runtime\section_brep\trial1 --export-images
|
||||
```
|
||||
|
||||
When `--image-views` is omitted, the tool exports seven baseline views:
|
||||
`front,back,top,bottom,left,right,isometric`.
|
||||
|
||||
Section B-rep and section image export are disabled in the current workflow. Use assembly/component B-rep, component highlight images, part-file images, and internal component group context images instead.
|
||||
|
||||
Image export is implemented in `ModelImageExporter.cs`, separate from the B-rep extraction logic in `Program.cs`.
|
||||
|
||||
Image evidence families are hard workflow boundaries:
|
||||
|
||||
- `assembly_component_position`: component position and whole-component function only. It has two visibility variants:
|
||||
- `unobstructed` (`assembly_component_highlight_view`): the assembly's existing visibility state is preserved and the target instance is highlighted in place. The exporter hides no component in this mode.
|
||||
- `occluded_context` (`assembly_component_context_isolate_view`): only geometry-derived occlusion blockers are hidden. Direct contact or mate neighbors are always preserved, and unrelated non-blocking components keep their original visibility.
|
||||
These are complementary renderings of the same evidence family, not component evidence versus interface evidence. Use the first whenever the target is already readable in the assembly; use the second only for an actually occluded internal target.
|
||||
- `assembly_physical_interface` (`assembly_physical_interface_view`): physical contact/fit function only. Images isolate exactly two participating components and highlight the grouped interface faces. They must not be used as component-position or per-face part evidence.
|
||||
Planar interface facts are retained in the B-rep report, but ordinary single-plane contacts are not exported as `physical_interfaces` images because they are not fit-tolerance evidence. Planar interface images are only for multi-face/profile fits such as slots, keys, or prismatic locating contacts. Cylindrical interface images first require analytic cylinder axis, radius, and axial-range compatibility. The common axial range is checked in 2 mm slices; for each slice the actual angular intervals are obtained from the SolidWorks trimmed Face and its Loop/Edge boundaries, without face tessellation or triangle-grid overlap. One slice with a positive angular interval intersection is sufficient; no minimum overlap-area threshold is applied. Opposing face normals are still required so two exterior faces on the same theoretical cylinder are not treated as a hole/shaft fit.
|
||||
- `part_all_face_surface` (`functional_group_all_face_highlight`): post-functional-group part and surface diagnosis only. These images must not enter component-function or interface-function analysis.
|
||||
- `part_feature_surface` (`part_feature_highlight_view`): direct-part feature evidence only.
|
||||
|
||||
`ImageKind` remains the concrete renderer/output type for compatibility. `EvidenceFamily` controls which AI stage may consume an image. Do not route images by filename alone.
|
||||
|
||||
Outputs:
|
||||
|
||||
- `section_brep_report.json`: assembly/component B-rep facts, face/contact facts, `FeatureGraph`, `SemanticFusionContract`, optional `ImageExport`, and empty legacy section fields.
|
||||
- `section_brep_report.md`: readable summary with exported image paths.
|
||||
- `model_images\*.jpg`: SolidWorks standard-view and section-view screenshots when image export is enabled.
|
||||
|
||||
Supported image views:
|
||||
|
||||
- `front`
|
||||
- `back`
|
||||
- `left`
|
||||
- `right`
|
||||
- `top`
|
||||
- `bottom`
|
||||
- `isometric`
|
||||
- `trimetric`
|
||||
- `dimetric`
|
||||
|
||||
Supported section planes:
|
||||
|
||||
- `front`
|
||||
- `top`
|
||||
- `right`
|
||||
|
||||
Feature graph:
|
||||
|
||||
The extractor also emits `FeatureGraph` as the B-rep side of the image/B-rep fusion layer. The first version groups raw faces into:
|
||||
|
||||
- `hole_group` / `hole_feature`
|
||||
- `main_axis_cylindrical_surface_group`
|
||||
- `cylindrical_surface_group`
|
||||
- `planar_pad_step_or_face_candidate`
|
||||
- assembly contact features when contacts exist
|
||||
|
||||
Each feature keeps source face refs and lists `VisualObservationNeeds` plus `RequiredBrepChecks` so AI diagnostics can combine image cues with measurable B-rep facts instead of treating either source as absolute.
|
||||
|
||||
Semantic fusion contract:
|
||||
|
||||
The extractor emits `SemanticFusionContract` as the machine-readable instruction boundary for AI diagnosis. It does not generate final mechanical semantics in code. Instead, it defines:
|
||||
|
||||
- the required pipeline from B-rep facts and images to a global mechanical semantic graph, then to local semantic units;
|
||||
- supported B-rep feature types;
|
||||
- semantic assertion types such as `part_identity`, `structural_semantic`, `functional_semantic`, `manufacturing_semantic`, `assembly_semantic`, and `risk_semantic`;
|
||||
- retrieval views, local semantic unit schema, B-rep fact bundle schema, confidence/status policy, missing-check fields, retrieval policy, and dedup policy.
|
||||
|
||||
At diagnosis time, the AI uses this contract plus `FeatureGraph`, raw B-rep facts, standard images, and section images to generate the actual mechanical semantic graph. Then it generates knowledge-blind `LocalSemanticUnit` objects: one neutral retrieval sentence plus concrete B-rep/image facts. Rule ids and final judgements are added only after knowledge retrieval and detailed rule verification.
|
||||
|
||||
Assembly diagnosis scope:
|
||||
|
||||
- For `SLDASM` input, diagnose both assembly-level relations and part-level structure.
|
||||
- Standard or purchased components are marked `review_scope=assembly_context_only`; they are used for mating context, accessibility, and standard-part selection/calculation checks, but not for nonstandard part-structure taboo checks.
|
||||
- Nonstandard or self-designed components are marked `review_scope=part_design_required`; AI must generate local semantic units for their local shape, surfaces, holes/slots/bosses/ribs, machining accessibility, stiffness, and other part-design views.
|
||||
|
||||
For assembly input, the report also emits two alignment structures:
|
||||
|
||||
- `ComponentEvidencePackages`: one package per SolidWorks component instance. It partitions assembly-derived B-rep faces, feature ids, and contact ids by component so evidence from different parts is not mixed.
|
||||
- `PartImagePlan`: image-export plan for components with `review_scope=part_design_required`. These images may come from the component part file, but their geometry facts must still use the component's B-rep subset extracted from the assembly. Do not re-extract part B-rep independently and merge it into the assembly report.
|
||||
|
||||
Diagnosis order for assemblies:
|
||||
|
||||
1. Analyze assembly-level design issues first: contacts, fits, locating, support, disassembly, accessibility, motion/interference, sealing, and lubrication.
|
||||
2. Then analyze each nonstandard/self-designed component's part-design issues using its `ComponentEvidencePackage` plus the matching `PartImagePlan` images.
|
||||
3. Standard or purchased components remain assembly context unless the specific rule is about standard-part selection or calculation.
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<NoWarn>$(NoWarn);CA1416</NoWarn>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SolidWorks.Interop.sldworks" Version="32.1.0" />
|
||||
<PackageReference Include="SolidWorks.Interop.swconst" Version="32.1.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"runtimeTarget": {
|
||||
"name": ".NETCoreApp,Version=v8.0",
|
||||
"signature": ""
|
||||
},
|
||||
"compilationOptions": {},
|
||||
"targets": {
|
||||
".NETCoreApp,Version=v8.0": {
|
||||
"SectionBrepExtractor/1.0.0": {
|
||||
"dependencies": {
|
||||
"SolidWorks.Interop.sldworks": "32.1.0",
|
||||
"SolidWorks.Interop.swconst": "32.1.0"
|
||||
},
|
||||
"runtime": {
|
||||
"SectionBrepExtractor.dll": {}
|
||||
}
|
||||
},
|
||||
"SolidWorks.Interop.sldworks/32.1.0": {
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/SolidWorks.Interop.sldworks.dll": {
|
||||
"assemblyVersion": "32.1.0.123",
|
||||
"fileVersion": "32.1.0.123"
|
||||
}
|
||||
}
|
||||
},
|
||||
"SolidWorks.Interop.swconst/32.1.0": {
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/SolidWorks.Interop.swconst.dll": {
|
||||
"assemblyVersion": "32.1.0.123",
|
||||
"fileVersion": "32.1.0.123"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"SectionBrepExtractor/1.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"SolidWorks.Interop.sldworks/32.1.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-lq3QmJwBbVE3K+pN5JFSGn1Bj7J1vUyTr4TtT23UAOtd8MXLElZROm9Iee2N8SP8AXsLTpXdBXGs7xYeJT53qw==",
|
||||
"path": "solidworks.interop.sldworks/32.1.0",
|
||||
"hashPath": "solidworks.interop.sldworks.32.1.0.nupkg.sha512"
|
||||
},
|
||||
"SolidWorks.Interop.swconst/32.1.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-mOLeWDKf0hX7iSNmdc22FmwoCaqH3KuNhODNGdWuT36KB/maGzQdfU+r9YS97n3mMIdWN3qaLBQ4eJG8z77rMw==",
|
||||
"path": "solidworks.interop.swconst/32.1.0",
|
||||
"hashPath": "solidworks.interop.swconst.32.1.0.nupkg.sha512"
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+13
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"runtimeOptions": {
|
||||
"tfm": "net8.0",
|
||||
"framework": {
|
||||
"name": "Microsoft.NETCore.App",
|
||||
"version": "8.0.0"
|
||||
},
|
||||
"configProperties": {
|
||||
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false,
|
||||
"CSWINRT_USE_WINDOWS_UI_XAML_PROJECTIONS": false
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
+57
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"runtimeTarget": {
|
||||
"name": ".NETCoreApp,Version=v8.0",
|
||||
"signature": ""
|
||||
},
|
||||
"compilationOptions": {},
|
||||
"targets": {
|
||||
".NETCoreApp,Version=v8.0": {
|
||||
"SectionBrepExtractor/1.0.0": {
|
||||
"dependencies": {
|
||||
"SolidWorks.Interop.sldworks": "32.1.0",
|
||||
"SolidWorks.Interop.swconst": "32.1.0"
|
||||
},
|
||||
"runtime": {
|
||||
"SectionBrepExtractor.dll": {}
|
||||
}
|
||||
},
|
||||
"SolidWorks.Interop.sldworks/32.1.0": {
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/SolidWorks.Interop.sldworks.dll": {
|
||||
"assemblyVersion": "32.1.0.123",
|
||||
"fileVersion": "32.1.0.123"
|
||||
}
|
||||
}
|
||||
},
|
||||
"SolidWorks.Interop.swconst/32.1.0": {
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/SolidWorks.Interop.swconst.dll": {
|
||||
"assemblyVersion": "32.1.0.123",
|
||||
"fileVersion": "32.1.0.123"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"SectionBrepExtractor/1.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"SolidWorks.Interop.sldworks/32.1.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-lq3QmJwBbVE3K+pN5JFSGn1Bj7J1vUyTr4TtT23UAOtd8MXLElZROm9Iee2N8SP8AXsLTpXdBXGs7xYeJT53qw==",
|
||||
"path": "solidworks.interop.sldworks/32.1.0",
|
||||
"hashPath": "solidworks.interop.sldworks.32.1.0.nupkg.sha512"
|
||||
},
|
||||
"SolidWorks.Interop.swconst/32.1.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-mOLeWDKf0hX7iSNmdc22FmwoCaqH3KuNhODNGdWuT36KB/maGzQdfU+r9YS97n3mMIdWN3qaLBQ4eJG8z77rMw==",
|
||||
"path": "solidworks.interop.swconst/32.1.0",
|
||||
"hashPath": "solidworks.interop.swconst.32.1.0.nupkg.sha512"
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+14
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"runtimeOptions": {
|
||||
"tfm": "net8.0",
|
||||
"framework": {
|
||||
"name": "Microsoft.NETCore.App",
|
||||
"version": "8.0.0"
|
||||
},
|
||||
"configProperties": {
|
||||
"System.Reflection.Metadata.MetadataUpdater.IsSupported": false,
|
||||
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false,
|
||||
"CSWINRT_USE_WINDOWS_UI_XAML_PROJECTIONS": false
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
+4
@@ -0,0 +1,4 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("SectionBrepExtractor")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+1bdf41f4900b623dd9948b3fc71ac3bb71e8e8e4")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("SectionBrepExtractor")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("SectionBrepExtractor")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Runtime.Versioning.TargetPlatformAttribute("Windows7.0")]
|
||||
[assembly: System.Runtime.Versioning.SupportedOSPlatformAttribute("Windows7.0")]
|
||||
|
||||
// Generated by the MSBuild WriteCodeFragment class.
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
e0d52fd083d15feeb9edc676163068d473a3e40a719480780b00c952c06952c2
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
is_global = true
|
||||
build_property.TargetFramework = net8.0-windows
|
||||
build_property.TargetFrameworkIdentifier = .NETCoreApp
|
||||
build_property.TargetFrameworkVersion = v8.0
|
||||
build_property.TargetPlatformMinVersion = 7.0
|
||||
build_property.UsingMicrosoftNETSdkWeb =
|
||||
build_property.ProjectTypeGuids =
|
||||
build_property.InvariantGlobalization =
|
||||
build_property.PlatformNeutralAssembly =
|
||||
build_property.EnforceExtendedAnalyzerRules =
|
||||
build_property.EntryPointFilePath =
|
||||
build_property._SupportedPlatformList = Linux,macOS,Windows
|
||||
build_property.RootNamespace = SectionBrepExtractor
|
||||
build_property.ProjectDir = D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\
|
||||
build_property.EnableComHosting =
|
||||
build_property.EnableGeneratedComInterfaceComImportInterop =
|
||||
build_property.CsWinRTUseWindowsUIXamlProjections = false
|
||||
build_property.EffectiveAnalysisLevelStyle = 8.0
|
||||
build_property.EnableCodeStyleSeverity =
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// <auto-generated/>
|
||||
global using System;
|
||||
global using System.Collections.Generic;
|
||||
global using System.IO;
|
||||
global using System.Linq;
|
||||
global using System.Net.Http;
|
||||
global using System.Threading;
|
||||
global using System.Threading.Tasks;
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
+1
@@ -0,0 +1 @@
|
||||
3bf86a3a67add5a7744ad92490ed4a208bb57db2cccadbb013d27a19957e1432
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\bin\Debug\net8.0-windows\SectionBrepExtractor.exe
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\bin\Debug\net8.0-windows\SectionBrepExtractor.deps.json
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\bin\Debug\net8.0-windows\SectionBrepExtractor.runtimeconfig.json
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\bin\Debug\net8.0-windows\SectionBrepExtractor.dll
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\bin\Debug\net8.0-windows\SectionBrepExtractor.pdb
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\bin\Debug\net8.0-windows\SolidWorks.Interop.sldworks.dll
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\bin\Debug\net8.0-windows\SolidWorks.Interop.swconst.dll
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\obj\Debug\net8.0-windows\SectionBrepExtractor.csproj.AssemblyReference.cache
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\obj\Debug\net8.0-windows\SectionBrepExtractor.GeneratedMSBuildEditorConfig.editorconfig
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\obj\Debug\net8.0-windows\SectionBrepExtractor.AssemblyInfoInputs.cache
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\obj\Debug\net8.0-windows\SectionBrepExtractor.AssemblyInfo.cs
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\obj\Debug\net8.0-windows\SectionBrepExtractor.csproj.CoreCompileInputs.cache
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\obj\Debug\net8.0-windows\SectionB.FFBBF4A1.Up2Date
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\obj\Debug\net8.0-windows\SectionBrepExtractor.dll
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\obj\Debug\net8.0-windows\refint\SectionBrepExtractor.dll
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\obj\Debug\net8.0-windows\SectionBrepExtractor.pdb
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\obj\Debug\net8.0-windows\SectionBrepExtractor.genruntimeconfig.cache
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\obj\Debug\net8.0-windows\ref\SectionBrepExtractor.dll
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\bin\Debug\net8.0-windows\SectionBrepExtractor.exe
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\bin\Debug\net8.0-windows\SectionBrepExtractor.deps.json
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\bin\Debug\net8.0-windows\SectionBrepExtractor.runtimeconfig.json
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\bin\Debug\net8.0-windows\SectionBrepExtractor.dll
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\bin\Debug\net8.0-windows\SectionBrepExtractor.pdb
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\bin\Debug\net8.0-windows\SolidWorks.Interop.sldworks.dll
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\bin\Debug\net8.0-windows\SolidWorks.Interop.swconst.dll
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\obj\Debug\net8.0-windows\SectionBrepExtractor.csproj.AssemblyReference.cache
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\obj\Debug\net8.0-windows\SectionBrepExtractor.GeneratedMSBuildEditorConfig.editorconfig
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\obj\Debug\net8.0-windows\SectionBrepExtractor.AssemblyInfoInputs.cache
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\obj\Debug\net8.0-windows\SectionBrepExtractor.AssemblyInfo.cs
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\obj\Debug\net8.0-windows\SectionBrepExtractor.csproj.CoreCompileInputs.cache
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\obj\Debug\net8.0-windows\SectionB.FFBBF4A1.Up2Date
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\obj\Debug\net8.0-windows\SectionBrepExtractor.dll
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\obj\Debug\net8.0-windows\refint\SectionBrepExtractor.dll
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\obj\Debug\net8.0-windows\SectionBrepExtractor.pdb
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\obj\Debug\net8.0-windows\SectionBrepExtractor.genruntimeconfig.cache
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\obj\Debug\net8.0-windows\ref\SectionBrepExtractor.dll
|
||||
D:\CSharpProjects\agent4\.tmp\buildcheck\SectionBrepExtractor\SectionBrepExtractor.exe
|
||||
D:\CSharpProjects\agent4\.tmp\buildcheck\SectionBrepExtractor\SectionBrepExtractor.deps.json
|
||||
D:\CSharpProjects\agent4\.tmp\buildcheck\SectionBrepExtractor\SectionBrepExtractor.runtimeconfig.json
|
||||
D:\CSharpProjects\agent4\.tmp\buildcheck\SectionBrepExtractor\SectionBrepExtractor.dll
|
||||
D:\CSharpProjects\agent4\.tmp\buildcheck\SectionBrepExtractor\SectionBrepExtractor.pdb
|
||||
BIN
Binary file not shown.
+1
@@ -0,0 +1 @@
|
||||
eb1ce21679dd92b145d1cdc40d2b97dc51c457f4bf453243d4fe9be812633e07
|
||||
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+4
@@ -0,0 +1,4 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("SectionBrepExtractor")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+1bdf41f4900b623dd9948b3fc71ac3bb71e8e8e4")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("SectionBrepExtractor")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("SectionBrepExtractor")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Runtime.Versioning.TargetPlatformAttribute("Windows7.0")]
|
||||
[assembly: System.Runtime.Versioning.SupportedOSPlatformAttribute("Windows7.0")]
|
||||
|
||||
// Generated by the MSBuild WriteCodeFragment class.
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
eedabf9ecf2e494bda3ce01b91dbe06275088be3b51605f222954bff0309539a
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
is_global = true
|
||||
build_property.TargetFramework = net8.0-windows
|
||||
build_property.TargetFrameworkIdentifier = .NETCoreApp
|
||||
build_property.TargetFrameworkVersion = v8.0
|
||||
build_property.TargetPlatformMinVersion = 7.0
|
||||
build_property.UsingMicrosoftNETSdkWeb =
|
||||
build_property.ProjectTypeGuids =
|
||||
build_property.InvariantGlobalization =
|
||||
build_property.PlatformNeutralAssembly =
|
||||
build_property.EnforceExtendedAnalyzerRules =
|
||||
build_property.EntryPointFilePath =
|
||||
build_property._SupportedPlatformList = Linux,macOS,Windows
|
||||
build_property.RootNamespace = SectionBrepExtractor
|
||||
build_property.ProjectDir = D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\
|
||||
build_property.EnableComHosting =
|
||||
build_property.EnableGeneratedComInterfaceComImportInterop =
|
||||
build_property.CsWinRTUseWindowsUIXamlProjections = false
|
||||
build_property.EffectiveAnalysisLevelStyle = 8.0
|
||||
build_property.EnableCodeStyleSeverity =
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// <auto-generated/>
|
||||
global using System;
|
||||
global using System.Collections.Generic;
|
||||
global using System.IO;
|
||||
global using System.Linq;
|
||||
global using System.Net.Http;
|
||||
global using System.Threading;
|
||||
global using System.Threading.Tasks;
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
+1
@@ -0,0 +1 @@
|
||||
a03aa3e5815a45196bdfa3c23942adab1219bdb8a32240081bf0dd1471b1a01f
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\bin\Release\net8.0-windows\SectionBrepExtractor.exe
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\bin\Release\net8.0-windows\SectionBrepExtractor.deps.json
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\bin\Release\net8.0-windows\SectionBrepExtractor.runtimeconfig.json
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\bin\Release\net8.0-windows\SectionBrepExtractor.dll
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\bin\Release\net8.0-windows\SectionBrepExtractor.pdb
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\bin\Release\net8.0-windows\SolidWorks.Interop.sldworks.dll
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\bin\Release\net8.0-windows\SolidWorks.Interop.swconst.dll
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\obj\Release\net8.0-windows\SectionBrepExtractor.csproj.AssemblyReference.cache
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\obj\Release\net8.0-windows\SectionBrepExtractor.GeneratedMSBuildEditorConfig.editorconfig
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\obj\Release\net8.0-windows\SectionBrepExtractor.AssemblyInfoInputs.cache
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\obj\Release\net8.0-windows\SectionBrepExtractor.AssemblyInfo.cs
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\obj\Release\net8.0-windows\SectionBrepExtractor.csproj.CoreCompileInputs.cache
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\obj\Release\net8.0-windows\SectionB.FFBBF4A1.Up2Date
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\obj\Release\net8.0-windows\SectionBrepExtractor.dll
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\obj\Release\net8.0-windows\refint\SectionBrepExtractor.dll
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\obj\Release\net8.0-windows\SectionBrepExtractor.pdb
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\obj\Release\net8.0-windows\SectionBrepExtractor.genruntimeconfig.cache
|
||||
D:\CSharpProjects\agent4\tools\SectionBrepExtractor\obj\Release\net8.0-windows\ref\SectionBrepExtractor.dll
|
||||
D:\CSharpProjects\agent4\.tmp\SectionBrepExtractor-build\SectionBrepExtractor.exe
|
||||
D:\CSharpProjects\agent4\.tmp\SectionBrepExtractor-build\SectionBrepExtractor.deps.json
|
||||
D:\CSharpProjects\agent4\.tmp\SectionBrepExtractor-build\SectionBrepExtractor.runtimeconfig.json
|
||||
D:\CSharpProjects\agent4\.tmp\SectionBrepExtractor-build\SectionBrepExtractor.dll
|
||||
D:\CSharpProjects\agent4\.tmp\SectionBrepExtractor-build\SectionBrepExtractor.pdb
|
||||
D:\CSharpProjects\agent4\.tmp\build-check\SectionBrepExtractor\SectionBrepExtractor.exe
|
||||
D:\CSharpProjects\agent4\.tmp\build-check\SectionBrepExtractor\SectionBrepExtractor.deps.json
|
||||
D:\CSharpProjects\agent4\.tmp\build-check\SectionBrepExtractor\SectionBrepExtractor.runtimeconfig.json
|
||||
D:\CSharpProjects\agent4\.tmp\build-check\SectionBrepExtractor\SectionBrepExtractor.dll
|
||||
D:\CSharpProjects\agent4\.tmp\build-check\SectionBrepExtractor\SectionBrepExtractor.pdb
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\bin\Release\net8.0-windows\SectionBrepExtractor.exe
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\bin\Release\net8.0-windows\SectionBrepExtractor.deps.json
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\bin\Release\net8.0-windows\SectionBrepExtractor.runtimeconfig.json
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\bin\Release\net8.0-windows\SectionBrepExtractor.dll
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\bin\Release\net8.0-windows\SectionBrepExtractor.pdb
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\bin\Release\net8.0-windows\SolidWorks.Interop.sldworks.dll
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\bin\Release\net8.0-windows\SolidWorks.Interop.swconst.dll
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\obj\Release\net8.0-windows\SectionBrepExtractor.csproj.AssemblyReference.cache
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\obj\Release\net8.0-windows\SectionBrepExtractor.GeneratedMSBuildEditorConfig.editorconfig
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\obj\Release\net8.0-windows\SectionBrepExtractor.AssemblyInfoInputs.cache
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\obj\Release\net8.0-windows\SectionBrepExtractor.AssemblyInfo.cs
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\obj\Release\net8.0-windows\SectionBrepExtractor.csproj.CoreCompileInputs.cache
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\obj\Release\net8.0-windows\SectionB.FFBBF4A1.Up2Date
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\obj\Release\net8.0-windows\SectionBrepExtractor.dll
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\obj\Release\net8.0-windows\refint\SectionBrepExtractor.dll
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\obj\Release\net8.0-windows\SectionBrepExtractor.pdb
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\obj\Release\net8.0-windows\SectionBrepExtractor.genruntimeconfig.cache
|
||||
D:\CSharpProjects\agent4\tools\model-diagnostics\SectionBrepExtractor\obj\Release\net8.0-windows\ref\SectionBrepExtractor.dll
|
||||
BIN
Binary file not shown.
+1
@@ -0,0 +1 @@
|
||||
c093f8b9ea37fef8e8cdab30c112d4072c7c376c7c3e1dc0dc59d952791a9838
|
||||
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+81
@@ -0,0 +1,81 @@
|
||||
{
|
||||
"format": 1,
|
||||
"restore": {
|
||||
"D:\\CSharpProjects\\agent4\\tools\\model-diagnostics\\SectionBrepExtractor\\SectionBrepExtractor.csproj": {}
|
||||
},
|
||||
"projects": {
|
||||
"D:\\CSharpProjects\\agent4\\tools\\model-diagnostics\\SectionBrepExtractor\\SectionBrepExtractor.csproj": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "D:\\CSharpProjects\\agent4\\tools\\model-diagnostics\\SectionBrepExtractor\\SectionBrepExtractor.csproj",
|
||||
"projectName": "SectionBrepExtractor",
|
||||
"projectPath": "D:\\CSharpProjects\\agent4\\tools\\model-diagnostics\\SectionBrepExtractor\\SectionBrepExtractor.csproj",
|
||||
"packagesPath": "C:\\Users\\86182\\.nuget\\packages\\",
|
||||
"outputPath": "D:\\CSharpProjects\\agent4\\tools\\model-diagnostics\\SectionBrepExtractor\\obj\\",
|
||||
"projectStyle": "PackageReference",
|
||||
"configFilePaths": [
|
||||
"C:\\Users\\86182\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net8.0-windows"
|
||||
],
|
||||
"sources": {
|
||||
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net8.0-windows": {
|
||||
"framework": "net8.0-windows7.0",
|
||||
"targetAlias": "net8.0-windows",
|
||||
"projectReferences": {}
|
||||
}
|
||||
},
|
||||
"warningProperties": {
|
||||
"warnAsError": [
|
||||
"NU1605"
|
||||
]
|
||||
},
|
||||
"restoreAuditProperties": {
|
||||
"enableAudit": "true",
|
||||
"auditLevel": "low",
|
||||
"auditMode": "direct"
|
||||
},
|
||||
"SdkAnalysisLevel": "10.0.300"
|
||||
},
|
||||
"frameworks": {
|
||||
"net8.0-windows": {
|
||||
"framework": "net8.0-windows7.0",
|
||||
"targetAlias": "net8.0-windows",
|
||||
"dependencies": {
|
||||
"SolidWorks.Interop.sldworks": {
|
||||
"target": "Package",
|
||||
"version": "[32.1.0, )"
|
||||
},
|
||||
"SolidWorks.Interop.swconst": {
|
||||
"target": "Package",
|
||||
"version": "[32.1.0, )"
|
||||
}
|
||||
},
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
"net47",
|
||||
"net471",
|
||||
"net472",
|
||||
"net48",
|
||||
"net481"
|
||||
],
|
||||
"assetTargetFallback": true,
|
||||
"warn": true,
|
||||
"frameworkReferences": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.300/PortableRuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
|
||||
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
|
||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\86182\.nuget\packages\</NuGetPackageFolders>
|
||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">7.0.0</NuGetToolVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<SourceRoot Include="C:\Users\86182\.nuget\packages\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
|
||||
@@ -0,0 +1,133 @@
|
||||
{
|
||||
"version": 4,
|
||||
"targets": {
|
||||
"net8.0-windows": {
|
||||
"SolidWorks.Interop.sldworks/32.1.0": {
|
||||
"type": "package",
|
||||
"compile": {
|
||||
"lib/netstandard2.0/SolidWorks.Interop.sldworks.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/SolidWorks.Interop.sldworks.dll": {}
|
||||
}
|
||||
},
|
||||
"SolidWorks.Interop.swconst/32.1.0": {
|
||||
"type": "package",
|
||||
"compile": {
|
||||
"lib/netstandard2.0/SolidWorks.Interop.swconst.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/SolidWorks.Interop.swconst.dll": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"SolidWorks.Interop.sldworks/32.1.0": {
|
||||
"sha512": "lq3QmJwBbVE3K+pN5JFSGn1Bj7J1vUyTr4TtT23UAOtd8MXLElZROm9Iee2N8SP8AXsLTpXdBXGs7xYeJT53qw==",
|
||||
"type": "package",
|
||||
"path": "solidworks.interop.sldworks/32.1.0",
|
||||
"files": [
|
||||
".nupkg.metadata",
|
||||
".signature.p7s",
|
||||
"lib/netstandard2.0/SolidWorks.Interop.sldworks.dll",
|
||||
"solidworks.interop.sldworks.32.1.0.nupkg.sha512",
|
||||
"solidworks.interop.sldworks.nuspec"
|
||||
]
|
||||
},
|
||||
"SolidWorks.Interop.swconst/32.1.0": {
|
||||
"sha512": "mOLeWDKf0hX7iSNmdc22FmwoCaqH3KuNhODNGdWuT36KB/maGzQdfU+r9YS97n3mMIdWN3qaLBQ4eJG8z77rMw==",
|
||||
"type": "package",
|
||||
"path": "solidworks.interop.swconst/32.1.0",
|
||||
"files": [
|
||||
".nupkg.metadata",
|
||||
".signature.p7s",
|
||||
"lib/netstandard2.0/SolidWorks.Interop.swconst.dll",
|
||||
"solidworks.interop.swconst.32.1.0.nupkg.sha512",
|
||||
"solidworks.interop.swconst.nuspec"
|
||||
]
|
||||
}
|
||||
},
|
||||
"projectFileDependencyGroups": {
|
||||
"net8.0-windows": [
|
||||
"SolidWorks.Interop.sldworks >= 32.1.0",
|
||||
"SolidWorks.Interop.swconst >= 32.1.0"
|
||||
]
|
||||
},
|
||||
"packageFolders": {
|
||||
"C:\\Users\\86182\\.nuget\\packages\\": {}
|
||||
},
|
||||
"project": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "D:\\CSharpProjects\\agent4\\tools\\model-diagnostics\\SectionBrepExtractor\\SectionBrepExtractor.csproj",
|
||||
"projectName": "SectionBrepExtractor",
|
||||
"projectPath": "D:\\CSharpProjects\\agent4\\tools\\model-diagnostics\\SectionBrepExtractor\\SectionBrepExtractor.csproj",
|
||||
"packagesPath": "C:\\Users\\86182\\.nuget\\packages\\",
|
||||
"outputPath": "D:\\CSharpProjects\\agent4\\tools\\model-diagnostics\\SectionBrepExtractor\\obj\\",
|
||||
"projectStyle": "PackageReference",
|
||||
"configFilePaths": [
|
||||
"C:\\Users\\86182\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net8.0-windows"
|
||||
],
|
||||
"sources": {
|
||||
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net8.0-windows": {
|
||||
"framework": "net8.0-windows7.0",
|
||||
"targetAlias": "net8.0-windows",
|
||||
"projectReferences": {}
|
||||
}
|
||||
},
|
||||
"warningProperties": {
|
||||
"warnAsError": [
|
||||
"NU1605"
|
||||
]
|
||||
},
|
||||
"restoreAuditProperties": {
|
||||
"enableAudit": "true",
|
||||
"auditLevel": "low",
|
||||
"auditMode": "direct"
|
||||
},
|
||||
"SdkAnalysisLevel": "10.0.300"
|
||||
},
|
||||
"frameworks": {
|
||||
"net8.0-windows": {
|
||||
"framework": "net8.0-windows7.0",
|
||||
"targetAlias": "net8.0-windows",
|
||||
"dependencies": {
|
||||
"SolidWorks.Interop.sldworks": {
|
||||
"target": "Package",
|
||||
"version": "[32.1.0, )"
|
||||
},
|
||||
"SolidWorks.Interop.swconst": {
|
||||
"target": "Package",
|
||||
"version": "[32.1.0, )"
|
||||
}
|
||||
},
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
"net47",
|
||||
"net471",
|
||||
"net472",
|
||||
"net48",
|
||||
"net481"
|
||||
],
|
||||
"assetTargetFallback": true,
|
||||
"warn": true,
|
||||
"frameworkReferences": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.300/PortableRuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dgSpecHash": "eeRaQVMf0fw=",
|
||||
"success": true,
|
||||
"projectFilePath": "D:\\CSharpProjects\\agent4\\tools\\model-diagnostics\\SectionBrepExtractor\\SectionBrepExtractor.csproj",
|
||||
"expectedPackageFiles": [
|
||||
"C:\\Users\\86182\\.nuget\\packages\\solidworks.interop.sldworks\\32.1.0\\solidworks.interop.sldworks.32.1.0.nupkg.sha512",
|
||||
"C:\\Users\\86182\\.nuget\\packages\\solidworks.interop.swconst\\32.1.0\\solidworks.interop.swconst.32.1.0.nupkg.sha512"
|
||||
],
|
||||
"logs": []
|
||||
}
|
||||
Reference in New Issue
Block a user