feat: resolve topology reference candidates
This commit is contained in:
@@ -7,7 +7,7 @@ import { createSqliteProjectPersistence, PersistenceWriteQueue, ProjectAutosaveS
|
||||
import { DependencyGraph } from '../src/facade/dependencyGraph'
|
||||
import { evaluateQuantityExpression, quantityFromNumber } from '../src/facade/units'
|
||||
import { createEdgeSubshapeRefs, createSubshapeRefs, createVertexSubshapeRefs, matchSubshapes, signatureForEdge, signatureForFace, signatureForVertex } from '../src/facade/topologyNaming'
|
||||
import { createPersistedTopoRef, migrateDocumentTopologyReferences, migrateTopoRefs, parseTopoRef, resolveTopoRef, serializeTopoRef } from '../src/facade/topologyReferences'
|
||||
import { createPersistedTopoRef, migrateDocumentTopologyReferences, migrateTopoRefs, parseTopoRef, resolveDocumentTopologyReference, resolveTopoRef, serializeTopoRef } from '../src/facade/topologyReferences'
|
||||
import { captureSignatureTopologyHistory } from '../src/facade/topologyHistory'
|
||||
import { assessResourceQuota, planResourceSweep } from '../src/facade/resourcePolicy'
|
||||
import { cloneSketch, createSketch, solveSketch } from '../src/facade/sketcher'
|
||||
@@ -887,6 +887,13 @@ test('generation topology migration updates LinkSub and external geometry withou
|
||||
assert.equal(external?.candidates?.length, 2)
|
||||
assert.deepEqual(ambiguous.changedOwnerIds, ['owner'])
|
||||
assert.deepEqual(ambiguous.issues.map((issue) => issue.referenceName), ['SupportFace', 'ExternalGeometry:external'])
|
||||
const propertyCandidate = external?.candidates?.[0] as string
|
||||
const resolvedProperty = resolveDocumentTopologyReference(document, { ownerObjectId: 'owner', referenceName: 'SupportFace', candidatePersistentId: propertyCandidate })
|
||||
assert.equal(resolvedProperty.status, 'stable')
|
||||
assert.equal(resolvedProperty.generation, 2)
|
||||
const externalCandidate = external?.candidates?.[1] as string
|
||||
assert.equal(resolveDocumentTopologyReference(document, { ownerObjectId: 'owner', referenceName: 'ExternalGeometry:external', candidatePersistentId: externalCandidate }).persistentId, externalCandidate)
|
||||
assert.throws(() => resolveDocumentTopologyReference(document, { ownerObjectId: 'owner', referenceName: 'SupportFace', candidatePersistentId: 'missing' }), /not available/)
|
||||
|
||||
const deletedMigration = migrateTopoRefs('source', previousEntries, [], 3)
|
||||
document.objects[0].topology = {
|
||||
@@ -916,6 +923,44 @@ test('generation topology migration updates LinkSub and external geometry withou
|
||||
assert.equal(resolvedAcrossGap.issues.length, 1)
|
||||
})
|
||||
|
||||
test('Facade topology replacement is versioned, rebuilds dependencies and is undoable', async () => {
|
||||
const face = { vertexCoord: [0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 2, 0], normalCoord: [], triIndexes: [0, 1, 2, 0, 2, 3] }
|
||||
const current = createSubshapeRefs('shape-current', 5, [face, face])
|
||||
const entries = current.refs.map((ref, index) => ({ ref, signature: current.signatures[index] }))
|
||||
const migration = migrateTopoRefs('source', [], entries, 5)
|
||||
const candidateIds = migration.matches.map((match) => match.current.persistentId)
|
||||
const reference = createPersistedTopoRef('source', { ...current.refs[0], status: 'ambiguous', candidates: candidateIds }, 4)
|
||||
const topology: ObjectTopologySnapshot = {
|
||||
shapeId: 'shape-current', documentVersion: 5, generation: 5, entries,
|
||||
migration: { previousGeneration: 4, matches: migration.matches },
|
||||
history: captureSignatureTopologyHistory('source:generation:5', [], entries),
|
||||
}
|
||||
const document: DocumentSnapshot = {
|
||||
...recomputeDocumentFixture(), id: 'doc-topology-repair', version: 5,
|
||||
tree: [{ id: 'source', label: 'Source', type: 'feature' }, { id: 'owner', label: 'Owner', type: 'feature' }],
|
||||
objects: [
|
||||
{ id: 'source', typeId: 'Part::Box', properties: [], topology },
|
||||
{ id: 'owner', typeId: 'PartDesign::Feature', properties: [{ name: 'SupportFace', label: 'Support face', group: 'Attachment', scope: 'data', type: 'App::PropertyLinkSub', value: reference, recompute: true }] },
|
||||
], dependencies: [{ sourceId: 'owner', targetId: 'source', relation: 'topo-ref', propertyName: 'SupportFace', reference: reference.persistentId }],
|
||||
recompute: { generation: 5, status: 'idle', objectStates: { source: 'up-to-date', owner: 'touched' }, dirtyObjects: ['owner'], order: [], errors: [] },
|
||||
}
|
||||
const facade = createMockFacade()
|
||||
await facade.project.save(document)
|
||||
await facade.app.document.load(document.id)
|
||||
const versionBefore = facade.app.document.getActive().version
|
||||
const resolved = facade.app.document.resolveTopologyReference({ ownerObjectId: 'owner', referenceName: 'SupportFace', candidatePersistentId: candidateIds[1] })
|
||||
assert.equal(resolved.status, 'stable')
|
||||
assert.equal(resolved.persistentId, candidateIds[1])
|
||||
assert.equal(facade.app.document.getActive().version, versionBefore + 1)
|
||||
assert.equal(facade.app.document.getActive().dirty, true)
|
||||
assert.equal(facade.app.document.getDependencies().find((edge) => edge.propertyName === 'SupportFace')?.reference, candidateIds[1])
|
||||
facade.history.undo()
|
||||
assert.equal((facade.app.document.getObject('owner')?.properties[0].value as typeof reference).status, 'ambiguous')
|
||||
facade.history.redo()
|
||||
assert.equal((facade.app.document.getObject('owner')?.properties[0].value as typeof reference).persistentId, candidateIds[1])
|
||||
facade.geometry.dispose()
|
||||
})
|
||||
|
||||
test('facade async recompute commits only an accepted generation', async () => {
|
||||
const facade = createMockFacade()
|
||||
facade.app.document.setProperty({ objectId: 'pad', propertyName: 'Length', value: 51 })
|
||||
|
||||
Reference in New Issue
Block a user