Volume interno tra superfici

Generalizzato per funzionare con superfici:


brep splits.gh (20,8 KB)

private void RunScript(List<Surface> s, ref object R)
  {
    // Creazione boundingbox globale contenente tutte le superfici
    Rhino.Geometry.BoundingBox bbox = Rhino.Geometry.BoundingBox.Empty;
    int n = s.Count;
    for(int i = 0;i < n;i++){
      Surface surf = s[i];
      bbox.Union(surf.GetBoundingBox(true));
    }
    
    // Aumentato boundingbox per avere margine negli step finali
    double d = bbox.Diagonal.Length;
    bbox.Inflate(+d / 100);
    
    // Esteso tutte le superfici per assicurare una completa intersezione con il bbox
    for(int i = 0;i < n;i++){
      s[i] = s[i].Extend(IsoStatus.East, d, true);
      s[i] = s[i].Extend(IsoStatus.North, d, true);
      s[i] = s[i].Extend(IsoStatus.South, d, true);
      s[i] = s[i].Extend(IsoStatus.West, d, true);
    }

    // Creata lista con tutti i frammenti da "tagliare"
    List<Brep> breps = new List<Brep>();
    breps.Add(bbox.ToBrep());

    // Ciclo iterativo, uno per ogni "cutter", per ogni superficie di taglio
    for(int i = 0;i < n;i++){
      Brep cutter = s[i].ToBrep();
      
      // Lista dove tenere i risultati dei tagli
      List<Brep> breps2 = new List<Brep>();
      
      // Operazione solida "split" per ogni frammento da tagliare con l'attuale cutter
      foreach(Brep brep in breps){
        Brep[] results = Rhino.Geometry.Brep.CreateBooleanSplit(brep, cutter, 0.01);
        if(results.Length == 0){
          // il cutter non ha intersecato il frammento, il frammento viene tenuto intero per i prossimi cicli
          breps2.Add(brep);
        }else{
          // il cutter ha intersecato il frammento, vengono tenuti i nuovi sotto-frammenti risultanti
          foreach(Brep result in results){
            breps2.Add(result);
          }
        }
      }
      breps = breps2;
    }

    
    List<Brep> results2 = new List<Brep>();
    
    // rimpicciolimento bbox
    bbox.Inflate(-d / 100);
    // salvata ogni brep che viene contenuta completamente dal bbox iniziale
    // in questo punto tutti i frammenti brep esterni perimetrali avranno una propria bbox che interseca con la bbox iniziale esattamente di "d"
    foreach(Brep brep in breps){
      if(bbox.Contains(brep.GetBoundingBox(true))){
        results2.Add(brep);
      }
    }

    R = results2;
  }

EDIT: aggiunti commenti nel codice qua ^ , @luca.filippone

3 Mi Piace