iTwin / imodel-transformer

API for exporting an iModel's parts and also importing them into another iModel
MIT License
3 stars 2 forks source link

Failed to merge imodels using transformer related methods #159

Open MYDJH opened 4 months ago

MYDJH commented 4 months ago

"I encountered some issues while using the transformer to merge two iModels. When executing the method, I encountered error messages. I tried several approaches to merge, but all of them failed."

Attempting solutions 1:

async count(iModelDb: IModelDb, classFullName: string): Promise<number> {
    return iModelDb.withPreparedStatement(
      `SELECT COUNT(*) FROM ${classFullName}`,
      (statement: ECSqlStatement): number => {
        return DbResult.BE_SQLITE_ROW === statement.step()
          ? statement.getValue(0).getInteger()
          : 0;
      }
    );
  }
  async mergeFrist(req: any, res: any): Promise<string> {
    IModelHost.startup();
    const SourceFileName1 = "C:\\Users\\wwr\\Downloads\\a\\a.bim";
    const sourceFileName2 = "C:\\Users\\wwr\\Downloads\\b\\b.bim";
    const targetFile = "C:\\Users\\wwr\\Downloads\\c\\c.bim";

    const SrouceModel1 = SnapshotDb.openFile(SourceFileName1);
    const SrouceModel2 = SnapshotDb.openFile(sourceFileName2);

    const num1 = await this.count(SrouceModel1, "BisCore.Element"); 
    const num2 = await this.count(SrouceModel2, "BisCore.Element"); 
    console.log("num1 = " + num1.toString()); //Output 1194
    console.log("num2 = " + num2.toString()); //Output 11943
    if (IModelJsFs.existsSync(targetFile)) {
      IModelJsFs.removeSync(targetFile);
    }
    const targetDbProps: CreateIModelProps = {
      rootSubject: { name: "Clone-Target" },
      ecefLocation: SrouceModel1.ecefLocation,
    };
    // Create a blank Imodel
    const targetDb = SnapshotDb.createEmpty(targetFile, targetDbProps);
    const transformer = new IModelTransformer(SrouceModel1,targetDb);
    await transformer.processSchemas();//Error Message:Error importing schema
    await transformer.processAll();//Error Message:attempt to clone with unknown class
    targetDb.saveChanges();

    const num4 = await this.count(targetDb, "BisCore.Element");

    SrouceModel1.close();
    targetDb.close();
    SrouceModel2.close();

    IModelHost.shutdown();
    return "Frist";
  }

Error Message:Error importing schema; Error Message:attempt to clone with unknown class;

Attempting solutions 2:

  async mergeSecond(req: any, res: any): Promise<string> {
    IModelHost.startup();
    const SourceFileName1 = "C:\\Users\\wwr\\Downloads\\a\\a.bim";
    const sourceFileName2 = "C:\\Users\\wwr\\Downloads\\b\\b.bim";
    const SrouceModel1 = SnapshotDb.openFile(SourceFileName1);
    const SrouceModel2 = SnapshotDb.openFile(sourceFileName2);
    const num1 = await this.count(SrouceModel1, "BisCore.Element"); //1194
    const num2 = await this.count(SrouceModel2, "BisCore.Element"); //11943
    const targetFileName = "C:\\Users\\wwr\\Downloads\\c\\c.bim";
    if (IModelJsFs.existsSync(targetFileName)) {
      IModelJsFs.removeSync(targetFileName);
    }
    const targetDbProps: CreateIModelProps = {
      rootSubject: { name: "Clone-Target" },
      ecefLocation: SrouceModel1.ecefLocation,
    };

    // Create a readable and writable file using a seed
    let TargetIModel1 = SnapshotDb.createFrom(SrouceModel1, targetFileName);
    const parentSubject = TargetIModel1.elements.getRootSubject().id;
    const subjectId1 = Subject.insert(TargetIModel1, parentSubject, "subject1");
    const subjectId2 = Subject.insert(TargetIModel1, parentSubject, "subject2");

    if (TargetIModel1.isReadonly) {
      console.log("readable");
    } else {
      console.log("readable and writable");
    }
    const transformer = new IModelTransformer(SrouceModel2,TargetIModel1,{
      targetScopeElementId: subjectId1,
    });
    await transformer.processSchemas();
    await transformer.processAll();//Error Error: attempt to clone with unknown class
    TargetIModel1.saveChanges();
    const num4 = await this.count(TargetIModel1, "BisCore.Element");
    SrouceModel1.close();
    SrouceModel2.close();
    TargetIModel1.close();
    return "Second";
  }
}

The actual error location is reported when executing the transformer. processAll() method

  public async processAll(): Promise<void> {
    Logger.logTrace(loggerCategory, "processAll()");
    this.logSettings();
    this.validateScopeProvenance();
    await this.initialize();
    await this.exporter.exportCodeSpecs();
    await this.exporter.exportFonts();
    await this.exporter.exportChildElements(IModel.rootSubjectId); Subject
    await this.exporter.exportModelContents(IModel.repositoryModelId, Element.classFullName, true);
    await this.exporter.exportSubModels(IModel.repositoryModelId); //Actual Error Position
    await this.exporter["exportAllAspects"](); 
    await this.exporter.exportRelationships(ElementRefersToElements.classFullName);
    await this.processDeferredElements();
    if (this.shouldDetectDeletes()) {
      await this.detectElementDeletes();
      await this.detectRelationshipDeletes();
    }

    if (this._options.optimizeGeometry)
      this.importer.optimizeGeometry(this._options.optimizeGeometry);

    this.importer.computeProjectExtents();
    this.finalizeTransformation();
  }

Error Message:Error Error: attempt to clone with unknown class

"I hope you can help me analyze whether the issue lies in my code or the environment, or if you have a better implementation plan. Thank you." The file I want to merge is. mergeFile.zip

nick4598 commented 2 months ago

Hello, are you still experiencing this issue?