OCC读取模型深度解析

1,StepFile_Read构造函数中for嵌套while循环导致

 sout << "      ...    STEP File   Read    ... " << endl;  
  c.Show(); 
#endif


//  Creation du StepReaderData

  LesTypes[rec_argNondef]    = Interface_ParamVoid ;
  LesTypes[rec_argSub]       = Interface_ParamSub ;
  LesTypes[rec_argIdent]     = Interface_ParamIdent ;
  LesTypes[rec_argInteger]   = Interface_ParamInteger ;
  LesTypes[rec_argFloat]     = Interface_ParamReal ;
  LesTypes[rec_argEnum]      = Interface_ParamEnum ;
  LesTypes[rec_argBinary]    = Interface_ParamBinary ;
  LesTypes[rec_argText]      = Interface_ParamText ;
  LesTypes[rec_argHexa]      = Interface_ParamHexa ;
  LesTypes[rec_argMisc]      = Interface_ParamMisc ;

  Standard_Integer nbhead, nbrec, nbpar;
  lir_file_nbr (&nbhead,&nbrec,&nbpar);  // renvoi par lex/yacc
  Handle(StepData_StepReaderData) undirec =
    new StepData_StepReaderData(nbhead,nbrec,nbpar);  // creation tableau de records

  for ( Standard_Integer nr = 1; nr <= nbrec; nr ++) {
    int nbarg; char* ident; char* typrec = 0;
    lir_file_rec (&ident, &typrec, &nbarg);
    undirec->SetRecord (nr, ident, typrec, nbarg);

    if (nbarg>0) {
      int typa; char* val;
      Interface_ParamType newtype;
      while(lir_file_arg (&typa, &val) == 1) {
        newtype = LesTypes[typa] ;
        undirec->AddStepParam (nr, val, newtype);
      }
    }
    undirec->InitParams(nr);
    lir_file_finrec();
  }
  lir_file_fin(1);
//  on a undirec pret pour la suite

#ifdef CHRONOMESURE
  sout << "      ... Step File loaded  ... " << endl; 

  1.1 Interface_FileReaderTool::LoadModel中的while导致速度慢

void Interface_FileReaderTool::LoadModel
  (const Handle(Interface_InterfaceModel)& amodel)
//
//   Methode generale de lecture d un fichier : il est lu via un FileReaderData
//   qui doit y donner acces de la facon la plus performante possible
//   chaque interface definit son FileHeader avec ses methodes, appelees ici
{
  // MGE 16/06/98
  // Building of Messages
  //====================================
  Handle(Message_Messenger) TF = Messenger();
  //====================================
  Handle(Interface_Check) ach = new Interface_Check;

  SetModel(amodel);

//  ..            Demarrage : Lecture du Header            ..
  if (theerrhand) {
    try {
      OCC_CATCH_SIGNALS
      BeginRead(amodel);  // selon la norme
    }
    catch (Standard_Failure) {
      // Sendinf of message : Internal error during the header reading
      Message_Msg Msg11("XSTEP_11");
      TF->Send (Msg11, Message_Info); 
    }
  }
  else
    BeginRead(amodel);  // selon la norme

  //  ..            Lecture des Entites            ..

  amodel->Reservate (thereader->NbEntities());

  Standard_Integer num, num0 = thereader->FindNextRecord(0);
  num = num0;

  while (num > 0) {
    Standard_Integer ierr = 0;  // erreur sur analyse d une entite
    Handle(Standard_Transient) anent;
    try {
      OCC_CATCH_SIGNALS
      for (num = num0;  num > 0; num = thereader->FindNextRecord(num)) {
    num0 = num;

    //    Lecture sous protection contre crash
    //    (fait aussi AddEntity mais pas SetReportEntity)
    anent = LoadedEntity(num);

    //     Lecture non protegee : utile pour travailler avec dbx
////    else
////      anent = LoadedEntity(num);

    //   ..        Fin Lecture        ..
    if (anent.IsNull())  {
          // Sending of message : Number of ignored Null Entities  
      Message_Msg Msg21("XSTEP_21");
          Msg21.Arg(amodel->NbEntities());
          TF->Send (Msg21, Message_Info);
      continue;
    }
    //      LoadedEntity fait AddEntity MAIS PAS SetReport (en bloc a la fin)

      }    // ---- fin boucle sur entites
      num0 = 0;    // plus rien
    }      // ---- fin du try, le catch suit

    //   En cas d erreur NON PREVUE par l analyse, recuperation par defaut
    //   Attention : la recuperation peut elle-meme planter ... (cf ierr)
    catch (Standard_Failure const& anException) {
      //      Au passage suivant, on attaquera le record suivant
      num0 = thereader->FindNextRecord(num); //:g9 abv 28 May 98: tr8_as2_ug.stp - infinite cycle: (0);

#ifdef _WIN32
      if (anException.IsKind(STANDARD_TYPE(OSD_Exception))) ierr = 2;
#else
      if (anException.IsKind(STANDARD_TYPE(OSD_Signal))) ierr = 2;
#endif
//:abv 03Apr00: anent is actually a previous one:      if (anent.IsNull()) 
      anent = thereader->BoundEntity(num);
      if (anent.IsNull()) {
    if (thetrace > 0) 
    {
      // Sending of message : Number of ignored Null Entities  
      Message_Msg Msg21("XSTEP_21");
      Msg21.Arg(amodel->NbEntities()+1);
      TF->Send (Msg21, Message_Info);
      continue;
    }
      }
      /*Handle(Interface_Check)*/ ach = new Interface_Check(anent);
      //: abv 03 Apr 00: trj3_s1-tc-214.stp: generate a message on exception
      Message_Msg Msg278("XSTEP_278");
      Msg278.Arg(amodel->StringLabel(anent));
      ach->SendFail (Msg278); 
      
      if (ierr == 2) {
       // Sending of message : reading of entity failed  
    Message_Msg Msg22("XSTEP_22");
        Msg22.Arg(amodel->StringLabel(anent));
        TF->Send (Msg22, Message_Info); 
    return;
      }

      if (!ierr) {
    //char mess[100]; svv #2
    ierr = 1;
// ce qui serait bien ici serait de recuperer le texte de l erreur pour ach ...
    if (thetrace > 0) {
      // Sending of message : recovered entity  
      Message_Msg Msg23("XSTEP_23");
      Msg23.Arg(num);
      TF->Send (Msg23, Message_Info); 
    }

//  Finalement, on charge une Entite Inconnue
    thenbreps ++;
    Handle(Interface_ReportEntity) rep =
      new Interface_ReportEntity(ach,anent);
    Handle(Standard_Transient) undef = UnknownEntity();
    AnalyseRecord(num,undef,ach);
    rep->SetContent(undef);

    if (thereports.IsNull()) thereports =
      new TColStd_HArray1OfTransient (1,thereader->NbRecords());
    thenbreps ++;
    thereports->SetValue (num,rep);
        //if(isValid)
          amodel->AddEntity (anent);    // pas fait par LoadedEntity ...
      }
      else {
    if (thetrace > 0) {
      // Sending of message : reading of entity failed  
      Message_Msg Msg22("XSTEP_22");
      Msg22.Arg(amodel->StringLabel(anent));
      TF->Send (Msg22, Message_Info);
    }
//  On garde <rep> telle quelle : pas d analyse fichier supplementaire,
//  Mais la phase preliminaire eventuelle est conservee
//  (en particulier, on garde trace du Type lu du fichier, etc...)
      }
    }    // -----  fin complete du try/catch
  }      // -----  fin du while

//  ..        Ajout des Reports, silya
  if (!thereports.IsNull()) {
    if (thetrace > 0) 
    {
      // Sending of message : report   
      Message_Msg Msg24("XSTEP_24");
      Msg24.Arg(thenbreps);
      TF->Send (Msg24, Message_Info); 
    }
    amodel->Reservate (-thenbreps-10);
    thenbreps = thereports->Upper();
    for (Standard_Integer nr = 1; nr <= thenbreps; nr ++) {
      if (thereports->Value(nr).IsNull()) continue;
      Handle(Standard_Transient) anent = thereader->BoundEntity (nr);
      Handle(Interface_ReportEntity) rep =
    Handle(Interface_ReportEntity)::DownCast(thereports->Value(nr));
      amodel->SetReportEntity (-amodel->Number(anent),rep);
    }
  }

//   Conclusion : peut ne rien faire : selon necessite
  if (theerrhand) {
    try {
      OCC_CATCH_SIGNALS
      EndRead(amodel);  // selon la norme
    }
    catch (Standard_Failure) {
      // Sendinf of message : Internal error during the header reading
      Message_Msg Msg11("XSTEP_11");
      TF->Send (Msg11, Message_Info); 
    }
  }
  else
    EndRead(amodel);  // selon la norme
}

2,IGESFile_Read

猜你喜欢

转载自www.cnblogs.com/xyb617/p/12592879.html