feat: complete supported Sketcher and PartDesign ABI contract
This commit is contained in:
@@ -334,6 +334,26 @@ const nativeDataPropertyNames = new Map<string, ReadonlySet<string>>([
|
||||
['Part::Revolution', new Set(['Source', 'Base', 'Axis', 'AxisLink', 'Angle', 'Symmetric', 'Solid', 'FaceMakerClass'])],
|
||||
['Part::Loft', new Set(['Sections', 'Solid', 'Ruled', 'Closed', 'MaxDegree', 'Linearize'])],
|
||||
['Part::Sweep', new Set(['Sections', 'Spine', 'Solid', 'Frenet', 'Transition', 'Linearize'])],
|
||||
['PartDesign::Plane', new Set(['MapMode', 'AttachmentOffset'])],
|
||||
['PartDesign::Line', new Set(['MapMode', 'AttachmentOffset'])],
|
||||
['PartDesign::Point', new Set(['MapMode', 'AttachmentOffset'])],
|
||||
['PartDesign::ShapeBinder', new Set(['Support', 'TraceSupport'])],
|
||||
['PartDesign::Pad', new Set(['Profile', 'Length', 'Length2', 'Type', 'Type2', 'SideType', 'UpToFace', 'UpToFace2', 'TaperAngle', 'TaperAngle2', 'Reversed', 'Midplane', 'ReferenceAxis', 'AlongSketchNormal', 'UseCustomVector', 'Direction', 'Offset', 'Offset2'])],
|
||||
['PartDesign::Pocket', new Set(['Profile', 'Length', 'Length2', 'Type', 'Type2', 'SideType', 'UpToFace', 'UpToFace2', 'TaperAngle', 'TaperAngle2', 'Reversed', 'Midplane', 'ReferenceAxis', 'AlongSketchNormal', 'UseCustomVector', 'Direction', 'Offset', 'Offset2'])],
|
||||
['PartDesign::Revolution', new Set(['Profile', 'Angle', 'Angle2', 'Type', 'UpToFace', 'ReferenceAxis', 'Axis', 'Midplane', 'Reversed'])],
|
||||
['PartDesign::Groove', new Set(['Base', 'Profile', 'Angle', 'Angle2', 'Type', 'UpToFace', 'ReferenceAxis', 'Axis', 'Midplane', 'Reversed'])],
|
||||
['PartDesign::AdditiveLoft', new Set(['Profile', 'Sections', 'Ruled', 'Closed'])],
|
||||
['PartDesign::SubtractiveLoft', new Set(['Profile', 'Sections', 'Ruled', 'Closed'])],
|
||||
['PartDesign::AdditivePipe', new Set(['Profile', 'Spine', 'Transition', 'Mode', 'Transformation'])],
|
||||
['PartDesign::SubtractivePipe', new Set(['Profile', 'Spine', 'Transition', 'Mode', 'Transformation'])],
|
||||
['PartDesign::Fillet', new Set(['Base', 'Radius', 'UseAllEdges'])],
|
||||
['PartDesign::Chamfer', new Set(['Base', 'Size', 'Size2', 'Angle', 'ChamferType', 'FlipDirection', 'UseAllEdges'])],
|
||||
['PartDesign::Draft', new Set(['Base', 'Angle', 'Reversed'])],
|
||||
['PartDesign::Thickness', new Set(['Base', 'Value', 'Join', 'Mode', 'Reversed'])],
|
||||
['PartDesign::Mirrored', new Set(['Originals', 'TransformMode'])],
|
||||
['PartDesign::MultiTransform', new Set(['Originals', 'TransformMode', 'Transformations'])],
|
||||
['PartDesign::LinearPattern', new Set(['Originals', 'TransformMode', 'Occurrences', 'Length', 'Offset', 'Direction', 'Mode', 'Reversed', 'Spacings', 'SpacingPattern', 'Direction2', 'Mode2', 'Length2', 'Offset2', 'Occurrences2', 'Reversed2', 'Spacings2', 'SpacingPattern2'])],
|
||||
['PartDesign::PolarPattern', new Set(['Originals', 'TransformMode', 'Occurrences', 'Angle', 'Axis', 'Mode', 'Offset', 'Spacings', 'SpacingPattern', 'Reversed'])],
|
||||
['PartDesign::Hole', new Set(['Threaded', 'ModelThread', 'ThreadType', 'ThreadSize', 'ThreadClass', 'ThreadFit', 'Diameter', 'ThreadDiameter', 'ThreadDirection', 'HoleCutType', 'HoleCutCustomValues', 'HoleCutDiameter', 'HoleCutDepth', 'HoleCutCountersinkAngle', 'DepthType', 'Depth', 'DrillPoint', 'DrillPointAngle', 'DrillForDepth', 'Tapered', 'TaperedAngle', 'ThreadDepthType', 'ThreadDepth', 'UseCustomThreadClearance', 'CustomThreadClearance', 'BaseProfileType'])],
|
||||
['Part::Fuse', new Set(['Base', 'Tool', 'Refine'])],
|
||||
['Part::Cut', new Set(['Base', 'Tool', 'Refine'])],
|
||||
@@ -384,6 +404,9 @@ const sketchGeometryType = {
|
||||
circle: 'Part::GeomCircle',
|
||||
arc: 'Part::GeomArcOfCircle',
|
||||
ellipse: 'Part::GeomEllipse',
|
||||
arcEllipse: 'Part::GeomArcOfEllipse',
|
||||
arcHyperbola: 'Part::GeomArcOfHyperbola',
|
||||
arcParabola: 'Part::GeomArcOfParabola',
|
||||
bspline: 'Part::GeomBSplineCurve',
|
||||
} as const
|
||||
|
||||
@@ -393,6 +416,9 @@ const sketchGeometryPayloadXml = (geometry: SketchGeometry) => {
|
||||
if (geometry.type === 'circle') return `<Circle CenterX="${geometry.center.x}" CenterY="${geometry.center.y}" CenterZ="0" NormalX="0" NormalY="0" NormalZ="1" AngleXU="0" Radius="${geometry.radius}"/>`
|
||||
if (geometry.type === 'arc') return `<ArcOfCircle CenterX="${geometry.center.x}" CenterY="${geometry.center.y}" CenterZ="0" NormalX="0" NormalY="0" NormalZ="1" AngleXU="0" Radius="${geometry.radius}" StartAngle="${geometry.startAngle}" EndAngle="${geometry.endAngle}"/>`
|
||||
if (geometry.type === 'ellipse') return `<Ellipse CenterX="${geometry.center.x}" CenterY="${geometry.center.y}" CenterZ="0" NormalX="0" NormalY="0" NormalZ="1" MajorRadius="${geometry.majorRadius}" MinorRadius="${geometry.minorRadius}" AngleXU="${geometry.rotation}"/>`
|
||||
if (geometry.type === 'arcEllipse') return `<ArcOfEllipse CenterX="${geometry.center.x}" CenterY="${geometry.center.y}" CenterZ="0" NormalX="0" NormalY="0" NormalZ="1" MajorRadius="${geometry.majorRadius}" MinorRadius="${geometry.minorRadius}" AngleXU="${geometry.rotation}" StartAngle="${geometry.startAngle}" EndAngle="${geometry.endAngle}"/>`
|
||||
if (geometry.type === 'arcHyperbola') return `<ArcOfHyperbola CenterX="${geometry.center.x}" CenterY="${geometry.center.y}" CenterZ="0" NormalX="0" NormalY="0" NormalZ="1" MajorRadius="${geometry.majorRadius}" MinorRadius="${geometry.minorRadius}" AngleXU="${geometry.rotation}" StartAngle="${geometry.startAngle}" EndAngle="${geometry.endAngle}"/>`
|
||||
if (geometry.type === 'arcParabola') return `<ArcOfParabola CenterX="${geometry.center.x}" CenterY="${geometry.center.y}" CenterZ="0" NormalX="0" NormalY="0" NormalZ="1" Focal="${geometry.focal}" AngleXU="${geometry.rotation}" StartAngle="${geometry.startAngle}" EndAngle="${geometry.endAngle}"/>`
|
||||
const weights = geometry.weights ?? geometry.controlPoints.map(() => 1)
|
||||
const knotCount = geometry.controlPoints.length + geometry.degree + 1
|
||||
const knots = geometry.knots ?? Array.from({ length: knotCount }, (_, index) => {
|
||||
@@ -411,7 +437,7 @@ const sketchGeometryPayloadXml = (geometry: SketchGeometry) => {
|
||||
return `<BSplineCurve PolesCount="${geometry.controlPoints.length}" KnotsCount="${uniqueKnots.length}" Degree="${geometry.degree}" IsPeriodic="${geometry.periodic ? 1 : 0}">${poles}${knotXml}</BSplineCurve>`
|
||||
}
|
||||
|
||||
type SketchInternalAlignmentType = 1 | 2 | 3 | 4 | 9 | 10
|
||||
type SketchInternalAlignmentType = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11
|
||||
|
||||
type SketchInternalGeometryHelper = {
|
||||
key: string
|
||||
@@ -533,8 +559,8 @@ const sketchInternalGeometryPlan = (sketch: SketchSnapshot): SketchInternalGeome
|
||||
firstPosition: 1,
|
||||
geometry: { id: `Internal${helpers.size}`, type: 'point', position: bsplinePointAtParameter(target, uniqueKnots[constraint.internalGeometryIndex]), construction: true },
|
||||
})
|
||||
} else {
|
||||
if (target.type !== 'ellipse') throw new Error(`FCStd native Sketch InternalAlignment '${constraint.id}' requires ellipse geometry '${constraint.geometryId}'.`)
|
||||
} else if (constraint.alignmentType.startsWith('ellipse-')) {
|
||||
if (target.type !== 'ellipse' && target.type !== 'arcEllipse') throw new Error(`FCStd native Sketch InternalAlignment '${constraint.id}' requires ellipse geometry '${constraint.geometryId}'.`)
|
||||
const focusIndex = constraint.alignmentType === 'ellipse-focus' ? constraint.internalGeometryIndex : 0
|
||||
if ((constraint.alignmentType === 'ellipse-focus' && focusIndex !== 0 && focusIndex !== 1) || (constraint.alignmentType !== 'ellipse-focus' && constraint.internalGeometryIndex !== 0)) throw new RangeError(`FCStd native Sketch InternalAlignment '${constraint.id}' has an invalid ellipse internal index.`)
|
||||
const alignmentType = constraint.alignmentType === 'ellipse-major' ? 1 : constraint.alignmentType === 'ellipse-minor' ? 2 : focusIndex === 0 ? 3 : 4
|
||||
@@ -548,6 +574,31 @@ const sketchInternalGeometryPlan = (sketch: SketchSnapshot): SketchInternalGeome
|
||||
? { id: `Internal${helpers.size}`, type: 'line', start: { x: target.center.x + target.minorRadius * minorDirection.x, y: target.center.y + target.minorRadius * minorDirection.y }, end: { x: target.center.x - target.minorRadius * minorDirection.x, y: target.center.y - target.minorRadius * minorDirection.y }, construction: true }
|
||||
: { id: `Internal${helpers.size}`, type: 'point', position: { x: target.center.x + (alignmentType === 3 ? 1 : -1) * focalDistance * majorDirection.x, y: target.center.y + (alignmentType === 3 ? 1 : -1) * focalDistance * majorDirection.y }, construction: true }
|
||||
helper = helpers.get(key) ?? addHelper({ key, targetGeometryId: constraint.geometryId, alignmentType, internalAlignmentIndex: -1, webInternalGeometryIndex: constraint.internalGeometryIndex, firstPosition: alignmentType <= 2 ? 0 : 1, geometry })
|
||||
} else if (constraint.alignmentType.startsWith('hyperbola-')) {
|
||||
if (target.type !== 'arcHyperbola') throw new Error(`FCStd native Sketch InternalAlignment '${constraint.id}' requires hyperbola geometry '${constraint.geometryId}'.`)
|
||||
if (constraint.internalGeometryIndex !== 0) throw new RangeError(`FCStd native Sketch InternalAlignment '${constraint.id}' has an invalid hyperbola internal index.`)
|
||||
const alignmentType = constraint.alignmentType === 'hyperbola-major' ? 5 : constraint.alignmentType === 'hyperbola-minor' ? 6 : 7
|
||||
const key = `${constraint.geometryId}\0${constraint.alignmentType}\0${0}`
|
||||
const majorDirection = { x: Math.cos(target.rotation), y: Math.sin(target.rotation) }
|
||||
const minorDirection = { x: -majorDirection.y, y: majorDirection.x }
|
||||
const focalDistance = Math.sqrt(target.majorRadius * target.majorRadius + target.minorRadius * target.minorRadius)
|
||||
const geometry: SketchInternalGeometryHelper['geometry'] = alignmentType === 5
|
||||
? { id: `Internal${helpers.size}`, type: 'line', start: { x: target.center.x + target.majorRadius * majorDirection.x, y: target.center.y + target.majorRadius * majorDirection.y }, end: { x: target.center.x - target.majorRadius * majorDirection.x, y: target.center.y - target.majorRadius * majorDirection.y }, construction: true }
|
||||
: alignmentType === 6
|
||||
? { id: `Internal${helpers.size}`, type: 'line', start: { x: target.center.x + target.minorRadius * minorDirection.x, y: target.center.y + target.minorRadius * minorDirection.y }, end: { x: target.center.x - target.minorRadius * minorDirection.x, y: target.center.y - target.minorRadius * minorDirection.y }, construction: true }
|
||||
: { id: `Internal${helpers.size}`, type: 'point', position: { x: target.center.x + focalDistance * majorDirection.x, y: target.center.y + focalDistance * majorDirection.y }, construction: true }
|
||||
helper = helpers.get(key) ?? addHelper({ key, targetGeometryId: constraint.geometryId, alignmentType, internalAlignmentIndex: -1, webInternalGeometryIndex: 0, firstPosition: alignmentType <= 6 ? 0 : 1, geometry })
|
||||
} else {
|
||||
if (target.type !== 'arcParabola' || (constraint.alignmentType !== 'parabola-focus' && constraint.alignmentType !== 'parabola-focal-axis')) throw new Error(`FCStd native Sketch InternalAlignment '${constraint.id}' requires parabola geometry '${constraint.geometryId}'.`)
|
||||
if (constraint.internalGeometryIndex !== 0) throw new RangeError(`FCStd native Sketch InternalAlignment '${constraint.id}' has an invalid parabola internal index.`)
|
||||
const alignmentType = constraint.alignmentType === 'parabola-focus' ? 8 : 11
|
||||
const key = `${constraint.geometryId}\0${constraint.alignmentType}\0${0}`
|
||||
const direction = { x: Math.cos(target.rotation), y: Math.sin(target.rotation) }
|
||||
const focus = { x: target.center.x + target.focal * direction.x, y: target.center.y + target.focal * direction.y }
|
||||
const geometry: SketchInternalGeometryHelper['geometry'] = alignmentType === 8
|
||||
? { id: `Internal${helpers.size}`, type: 'point', position: focus, construction: true }
|
||||
: { id: `Internal${helpers.size}`, type: 'line', start: { ...target.center }, end: focus, construction: true }
|
||||
helper = helpers.get(key) ?? addHelper({ key, targetGeometryId: constraint.geometryId, alignmentType, internalAlignmentIndex: -1, webInternalGeometryIndex: 0, firstPosition: alignmentType === 8 ? 1 : 0, geometry })
|
||||
}
|
||||
if (helper.explicitAlignmentId) throw new Error(`FCStd native Sketch has duplicate InternalAlignment constraints for '${constraint.geometryId}' internal geometry ${constraint.internalGeometryIndex}.`)
|
||||
helper.explicitAlignmentId = constraint.id
|
||||
@@ -746,7 +797,7 @@ const sketchConstraintPoint = (geometryIndex: Map<string, number>, geometryById:
|
||||
if (!geometry) throw new RangeError(`FCStd Sketch ${context} references unknown geometry '${reference.geometryId}'.`)
|
||||
const valid = geometry.type === 'line' ? reference.point === 'start' || reference.point === 'end'
|
||||
: geometry.type === 'point' ? reference.point === 'position'
|
||||
: geometry.type === 'circle' || geometry.type === 'arc' || geometry.type === 'ellipse' ? reference.point === 'center'
|
||||
: geometry.type === 'circle' || geometry.type === 'arc' || geometry.type === 'ellipse' || geometry.type === 'arcEllipse' || geometry.type === 'arcHyperbola' || geometry.type === 'arcParabola' ? reference.point === 'center'
|
||||
: false
|
||||
if (!valid) throw new RangeError(`FCStd Sketch ${context} point '${reference.point}' is invalid for ${geometry.type} '${geometry.id}'.`)
|
||||
return sketchConstraintElement(geometryIndex, geometryById, reference.geometryId, sketchPointPosition[reference.point], context)
|
||||
@@ -1370,6 +1421,9 @@ const structuredPropertyValue = (element: string, elementValue: unknown, propert
|
||||
else if (type === 'Part::GeomCircle') value = { id: String(nativeId), type: 'circle', center: { x: finite(payload, 'CenterX'), y: finite(payload, 'CenterY') }, radius: finite(payload, 'Radius') }
|
||||
else if (type === 'Part::GeomArcOfCircle') value = { id: String(nativeId), type: 'arc', center: { x: finite(payload, 'CenterX'), y: finite(payload, 'CenterY') }, radius: finite(payload, 'Radius'), startAngle: finite(payload, 'StartAngle'), endAngle: finite(payload, 'EndAngle') }
|
||||
else if (type === 'Part::GeomEllipse') value = { id: String(nativeId), type: 'ellipse', center: { x: finite(payload, 'CenterX'), y: finite(payload, 'CenterY') }, majorRadius: finite(payload, 'MajorRadius'), minorRadius: finite(payload, 'MinorRadius'), rotation: finite(payload, 'AngleXU') }
|
||||
else if (type === 'Part::GeomArcOfEllipse') value = { id: String(nativeId), type: 'arcEllipse', center: { x: finite(payload, 'CenterX'), y: finite(payload, 'CenterY') }, majorRadius: finite(payload, 'MajorRadius'), minorRadius: finite(payload, 'MinorRadius'), rotation: finite(payload, 'AngleXU'), startAngle: finite(payload, 'StartAngle'), endAngle: finite(payload, 'EndAngle') }
|
||||
else if (type === 'Part::GeomArcOfHyperbola') value = { id: String(nativeId), type: 'arcHyperbola', center: { x: finite(payload, 'CenterX'), y: finite(payload, 'CenterY') }, majorRadius: finite(payload, 'MajorRadius'), minorRadius: finite(payload, 'MinorRadius'), rotation: finite(payload, 'AngleXU'), startAngle: finite(payload, 'StartAngle'), endAngle: finite(payload, 'EndAngle') }
|
||||
else if (type === 'Part::GeomArcOfParabola') value = { id: String(nativeId), type: 'arcParabola', center: { x: finite(payload, 'CenterX'), y: finite(payload, 'CenterY') }, focal: finite(payload, 'Focal'), rotation: finite(payload, 'AngleXU'), startAngle: finite(payload, 'StartAngle'), endAngle: finite(payload, 'EndAngle') }
|
||||
else if (type === 'Part::GeomBSplineCurve') {
|
||||
const curve = payload && typeof payload === 'object' ? payload as Record<string, unknown> : {}
|
||||
const poles = asArray(curve.Pole as Record<string, unknown> | Record<string, unknown>[] | undefined)
|
||||
@@ -1676,7 +1730,7 @@ const sketchFromPropertySummaries = (objectId: string, summaries: FcstdPropertyS
|
||||
const candidate = nativeGeometryForNativeId(nativeId)
|
||||
return candidate && !candidate.freecadInternalType ? candidate : undefined
|
||||
}
|
||||
type InternalHelperBinding = { geometryId: string; internalGeometryIndex: number; alignmentType: 'ellipse-major' | 'ellipse-minor' | 'ellipse-focus' | 'bspline-control-point' | 'bspline-knot' }
|
||||
type InternalHelperBinding = { geometryId: string; internalGeometryIndex: number; alignmentType: 'ellipse-major' | 'ellipse-minor' | 'ellipse-focus' | 'hyperbola-major' | 'hyperbola-minor' | 'hyperbola-focus' | 'parabola-focus' | 'parabola-focal-axis' | 'bspline-control-point' | 'bspline-knot' }
|
||||
const internalHelperBindings = new Map<number, InternalHelperBinding>()
|
||||
for (const record of constraints) {
|
||||
if (record.type !== 15) continue
|
||||
@@ -1688,11 +1742,20 @@ const sketchFromPropertySummaries = (objectId: string, summaries: FcstdPropertyS
|
||||
if (!helper || helper.freecadInternalType !== record.internalAlignmentType || !target || record.positions[1] !== 0 || record.ids[2] !== -2000 || record.positions[2] !== 0) return undefined
|
||||
let binding: InternalHelperBinding | undefined
|
||||
if (record.internalAlignmentType === 1 || record.internalAlignmentType === 2) {
|
||||
if (helper.type !== 'line' || target.type !== 'ellipse' || record.positions[0] !== 0 || record.internalAlignmentIndex !== -1) return undefined
|
||||
if (helper.type !== 'line' || (target.type !== 'ellipse' && target.type !== 'arcEllipse') || record.positions[0] !== 0 || record.internalAlignmentIndex !== -1) return undefined
|
||||
binding = { geometryId: target.id, internalGeometryIndex: 0, alignmentType: record.internalAlignmentType === 1 ? 'ellipse-major' : 'ellipse-minor' }
|
||||
} else if (record.internalAlignmentType === 3 || record.internalAlignmentType === 4) {
|
||||
if (helper.type !== 'point' || target.type !== 'ellipse' || record.positions[0] !== 1 || record.internalAlignmentIndex !== -1) return undefined
|
||||
if (helper.type !== 'point' || (target.type !== 'ellipse' && target.type !== 'arcEllipse') || record.positions[0] !== 1 || record.internalAlignmentIndex !== -1) return undefined
|
||||
binding = { geometryId: target.id, internalGeometryIndex: record.internalAlignmentType === 3 ? 0 : 1, alignmentType: 'ellipse-focus' }
|
||||
} else if (record.internalAlignmentType === 5 || record.internalAlignmentType === 6) {
|
||||
if (helper.type !== 'line' || target.type !== 'arcHyperbola' || record.positions[0] !== 0 || record.internalAlignmentIndex !== -1) return undefined
|
||||
binding = { geometryId: target.id, internalGeometryIndex: 0, alignmentType: record.internalAlignmentType === 5 ? 'hyperbola-major' : 'hyperbola-minor' }
|
||||
} else if (record.internalAlignmentType === 7) {
|
||||
if (helper.type !== 'point' || target.type !== 'arcHyperbola' || record.positions[0] !== 1 || record.internalAlignmentIndex !== -1) return undefined
|
||||
binding = { geometryId: target.id, internalGeometryIndex: 0, alignmentType: 'hyperbola-focus' }
|
||||
} else if (record.internalAlignmentType === 8) {
|
||||
if (helper.type !== 'point' || target.type !== 'arcParabola' || record.positions[0] !== 1 || record.internalAlignmentIndex !== -1) return undefined
|
||||
binding = { geometryId: target.id, internalGeometryIndex: 0, alignmentType: 'parabola-focus' }
|
||||
} else if (record.internalAlignmentType === 9) {
|
||||
if (helper.type !== 'circle' || target.type !== 'bspline' || record.positions[0] !== 3 || record.internalAlignmentIndex < 0 || record.internalAlignmentIndex >= target.controlPoints.length) return undefined
|
||||
binding = { geometryId: target.id, internalGeometryIndex: record.internalAlignmentIndex, alignmentType: 'bspline-control-point' }
|
||||
@@ -1701,6 +1764,9 @@ const sketchFromPropertySummaries = (objectId: string, summaries: FcstdPropertyS
|
||||
const uniqueKnots = bsplineExpandedKnots(target).filter((knot, index, knots) => index === 0 || knot !== knots[index - 1])
|
||||
if (record.internalAlignmentIndex < 0 || record.internalAlignmentIndex >= uniqueKnots.length) return undefined
|
||||
binding = { geometryId: target.id, internalGeometryIndex: record.internalAlignmentIndex, alignmentType: 'bspline-knot' }
|
||||
} else if (record.internalAlignmentType === 11) {
|
||||
if (helper.type !== 'line' || target.type !== 'arcParabola' || record.positions[0] !== 0 || record.internalAlignmentIndex !== -1) return undefined
|
||||
binding = { geometryId: target.id, internalGeometryIndex: 0, alignmentType: 'parabola-focal-axis' }
|
||||
} else return undefined
|
||||
const existing = internalHelperBindings.get(helperNativeId)
|
||||
if (existing && JSON.stringify(existing) !== JSON.stringify(binding)) throw new Error(`FCStd Sketch ${objectId} internal helper ${helperNativeId} has conflicting geometry bindings.`)
|
||||
@@ -1715,7 +1781,7 @@ const sketchFromPropertySummaries = (objectId: string, summaries: FcstdPropertyS
|
||||
const position = record.positions[slot]
|
||||
if (candidate.type === 'line') return position === 1 ? { geometryId: candidate.id, point: 'start' } : position === 2 ? { geometryId: candidate.id, point: 'end' } : undefined
|
||||
if (candidate.type === 'point') return position === 1 ? { geometryId: candidate.id, point: 'position' } : undefined
|
||||
if (candidate.type === 'circle' || candidate.type === 'arc' || candidate.type === 'ellipse') return position === 3 ? { geometryId: candidate.id, point: 'center' } : undefined
|
||||
if (candidate.type === 'circle' || candidate.type === 'arc' || candidate.type === 'ellipse' || candidate.type === 'arcEllipse' || candidate.type === 'arcHyperbola' || candidate.type === 'arcParabola') return position === 3 ? { geometryId: candidate.id, point: 'center' } : undefined
|
||||
return undefined
|
||||
}
|
||||
const geometryRef = (record: typeof constraints[number], slot: number) => geometryForNativeId(record.ids[slot])?.id
|
||||
|
||||
Reference in New Issue
Block a user