diff --git a/__test__/FileSystem/__snapshots__/wblockClone.test.ts.snap b/__test__/FileSystem/__snapshots__/wblockClone.test.ts.snap index 537078a69..254850371 100644 --- a/__test__/FileSystem/__snapshots__/wblockClone.test.ts.snap +++ b/__test__/FileSystem/__snapshots__/wblockClone.test.ts.snap @@ -91,7 +91,7 @@ Array [ false, 0, 2, - 1, + 2, "TextureTableRecord", 2, 101, @@ -106,6 +106,20 @@ Array [ 1, 0, "CAD/images/bd/bdfb0d6740912fc3217e3f9bfa4c53fd.png", + "TextureTableRecord", + 2, + 103, + false, + 4, + 1, + "贴图1(1)", + 1, + 1000, + 1002, + 1, + 1, + 0, + "CAD/images/bd/bdfb0d6740912fc3217e3f9bfa4c53fd.png", 2, 3, false, diff --git a/src/DatabaseServices/Database.ts b/src/DatabaseServices/Database.ts index 51c73ca91..2f6544ae5 100644 --- a/src/DatabaseServices/Database.ts +++ b/src/DatabaseServices/Database.ts @@ -146,116 +146,114 @@ export class Database /** * 将来自不同数据库的对象列表拷贝到本数据库中. + * 当前支持使用HardId模式来硬关联某个对象,使该对象能够在WblockClone时一起被带过来. + * 当前不支持硬关联对象的Owner不是默认的容器. + * 如果需要这么做,请将该对象的Owner设置为Hard关联 * @param objects 对象不能属于本数据库 * @param owner 克隆对象的新容器 * @param idMap id映射 */ - async WblockCloneObejcts( + WblockCloneObejcts( objects: CADObject[], owner: OwnerContainer, idMap: IdMaping, - drc: DuplicateRecordCloning, - drcf?: (name: string) => DuplicateRecordCloning + drc: DuplicateRecordCloning ) { - let f = new WblockCloneFiler(); - let clonedObjects: CADObject[] = []; + for (let obj of objects) + { + this.WblockCloneObject(obj, owner, idMap, drc, f); + } + + let oldDb = objects[0].Db; + + for (let [n, id] of f.hardMaping) + { + let oldId = oldDb.GetObjectId(n); + //使用旧的OwnerId得到新的OwnerId,假设所有者都是数据库默认存在的. + //TODO: 当OwnerId>100时,表示这个所有者不是数据库里面默认存在的,那么应该将Owner拷贝过来. + let newOwnerId = this.GetObjectId(oldId.Object.Owner.Index);//owner.Db === this + let newOwner = newOwnerId.Object as SymbolTable; + + this.WblockCloneObject(oldId.Object, newOwner, idMap, drc, f); + } + } + + private WblockCloneObject( + object: CADObject, + owner: OwnerContainer, + idMap: IdMaping, + drc: DuplicateRecordCloning, + filer: WblockCloneFiler + ) + { + filer.Data.length = 0; if (owner instanceof SymbolTable) { - for (let obj of objects) + let record = object as SymbolTableRecord; + let name = record.Name; + if (owner.Has(name))//名称重复 { - let record = obj as SymbolTableRecord; - let name = record.Name; - if (owner.Has(name))//名称重复 + let status = drc; + if (status === DuplicateRecordCloning.Rename) { - let status = drc; - if (drcf) - status = await drcf(name); - - if (status === DuplicateRecordCloning.Ignore) - continue; - - if (status === DuplicateRecordCloning.Rename) + //new name + for (let i = 1; ; i++) { - for (let i = 1; ; i++) + let nname = `${name}(${i})`; + if (!owner.Has(nname)) { - let nname = `${name}(${i})`; - if (!owner.Has(nname)) - { - name = nname; - break; - } + name = nname; + break; } - - f.Data.length = 0; - f.WriteObject(record); - let newRecord = f.ReadObject() as SymbolTableRecord; - newRecord.Owner = undefined; - newRecord.Name = name; - owner.Add(newRecord, false); - - newRecord.Id.Index = this.idIndex++; - this.idMap.set(newRecord.Id.Index, newRecord.Id); - idMap.set(obj.Id, newRecord.Id); } - else if (status === DuplicateRecordCloning.Replace) - { - let oldRecord = owner.GetAt(name); - //将f的id映射设置为旧的id - f.idMaping.set(obj.Id.Index, oldRecord.Id); - f.Data.length = 0; - record.WriteFile(f); - f.Reset(); + filer.WriteObject(record); + filer.Reset(); + let newRecord = filer.ReadObject() as SymbolTableRecord; + newRecord.Owner = undefined; + newRecord.Name = name; + owner.Add(newRecord, false); - //此时重新读取的话,将会得到原先的id,实现id不变 - oldRecord.ReadFile(f); - oldRecord.Owner = owner.Id; - } + this.AllocationObjectId(newRecord); + idMap.set(object.Id, newRecord.Id); } - else + else if (status === DuplicateRecordCloning.Replace) { - f.Data.length = 0; - f.WriteObject(record); - let newRecord = f.ReadObject() as SymbolTableRecord; - owner.Add(newRecord, false); + let oldRecord = owner.GetAt(name); + //将f的id映射设置为旧的id + filer.idMaping.set(object.Id.Index, oldRecord.Id); + + record.WriteFile(filer); + filer.Reset(); - newRecord.Id.Index = this.idIndex++; - this.idMap.set(newRecord.Id.Index, newRecord.Id); - idMap.set(obj.Id, newRecord.Id); - break; + //此时重新读取的话,将会得到原先的id,实现id不变 + oldRecord.ReadFile(filer); + oldRecord.Owner = owner.Id; + idMap.set(object.Id, oldRecord.Id); } + return; } } - else - { - f.CloneObjects(objects, clonedObjects); - this.CheapClone(f, idMap, owner); - } - - let oldDb = objects[0].Db; - - for (let [n, id] of f.hardMaping) - { - clonedObjects = []; - let oldId = oldDb.GetObjectId(n); - f.CloneObjects([oldId.Object], clonedObjects); - - //使用旧的OwnerId得到新的OwnerId,假设所有者都是数据库默认存在的. - //TODO: 当OwnerId>100时,表示这个所有者不是数据库里面默认存在的,那么应该将Owner拷贝过来. - let newOwnerId = this.GetObjectId(oldId.Object.Owner.Index);//owner.Db === this - let newOwner = newOwnerId.Object as SymbolTable; - newOwner.Add(clonedObjects[0] as SymbolTableRecord, false); + filer.WriteObject(object); + filer.Reset(); + let newObject = filer.ReadObject() as SymbolTableRecord; + owner.Add(newObject, false); - id.Index = this.idIndex++; - this.idMap.set(id.Index, id); + this.AllocationObjectId(newObject); + idMap.set(object.Id, newObject.Id); + } - idMap.set(oldId, id); - } - return clonedObjects; + /** + * 为拷贝出来的对象分配id索引,并在数据库中注册 + */ + private AllocationObjectId(object: CADObject) + { + object.Id.Index = this.idIndex++; + this.idMap.set(object.Id.Index, object.Id); } Insert()