How to select inner faces of square wall

sketchup

#1

hello i am trying to selected inner faces for wall , i used this code

mod = Sketchup.active_model # Open model
ent = mod.entities # All entities in model
sel = mod.selection # Current selection
faces = (sel[0].entities).grep Sketchup::Face
cf = (faces[0].all_connected).grep Sketchup::Face  

but this selecting all face in group


#2

Yea, you need to filter of the faces you want based on some distinguishable properties.

In this particular case we can use the fact that the inner faces will be connected to the inner loops of the bottom or top face.

module Example

  # Example.get_inner_wall_faces_of_selected_instance
  def self.get_inner_wall_faces_of_selected_instance
    model = Sketchup.active_model
    selection = model.selection
    instance = selection.first
    faces = self.get_inner_wall_faces(instance.entities)
    model.start_operation('Paint Inner Walls', true)
    faces.each { |face| face.material = 'red' }
    model.commit_operation
  end

  def self.get_inner_wall_faces(entities)
    faces = entities.grep(Sketchup::Face)
    # First we find the top face(s).
    top_faces = faces.select { |face|
      face.normal.samedirection?(Z_AXIS)
    }
    # Now we just need to iterate its inner loops and find connected faces.
    inner_wall_faces = []
    top_faces.each { |top_face|
      top_face.loops.each { |loop|
        next if loop.outer?
        inner_wall_faces.concat(self.inner_loop_faces(loop, top_face))
      }
    }
    inner_wall_faces
  end

  def self.inner_loop_faces(loop, ignore_face)
    faces = []
    loop.edges.each { |edge|
      edge_faces = edge.faces
      edge_faces.delete(ignore_face) # Don't want the top face
      faces.concat(edge_faces)
    }
    faces
  end

end

#3

thanks for response …
now i am trying to using pushpull tool for inner face it’s work correctly with wall on square shape and dose not with wall on pentagon or hexagon shape , after push inner faces i found intersection line on upper face and bottom face

mod = Sketchup.active_model 
ent = mod.entities
sel = mod.selection 
prom = ["Thikness"]
default = [""]
result = UI.inputbox prom , default , "Edit thikness"
thik = result[0].to_f
UI.messagebox thik
faces = sel[0].entities.grep(Sketchup::Face)
    # First we find the top face(s).
    top_faces = faces.select { |face|
      face.normal.samedirection?([0,0,-1])
    }
    sel.clear 
    faces = []
    edge_faces = []
   top_faces.each{|top| 
   #UI.messagebox top.loops.length
   top.loops.each{|l| next if l.outer? 
   l.edges.each{|e|  edge_faces = e.faces
   edge_faces.delete(top)
   faces.concat(edge_faces)
   }
   }
   }
   faces.each{|f|  
   u = Sketchup.active_model.options["UnitsOptions"]["LengthUnit"]
   case u 
   when 0
     f.pushpull thik.inch
   when 1 
     f.pushpull thik.feet
   when 2 
     f.pushpull thik.mm
   when 3
     f.pushpull thik.cm
   when 4 
     f.pushpull thik.m
   else 
     UI.messagebox "model doesn't have unit"
   end 
   
   }


#4

How would you draw this manually?


#5

by 1001bit tools


#6

And if no plugins were involved? Try to map your manual steps on your code.


#7

my code selected inner faces for wall and push it according to thickness


#8

How about drawing the bottom face first, as if it were a floorplan, and then just push-pull the face upward?


#9

the drawing dose not matter , my problem is how to modifying the thickness of wall after creation


#10

Learn to transform the inner wall vertices rather than using pushpull.


#11

@Ahmed1 - please format the code blocks you post. Use the </> button in the toolbar of the text editor. image

Makes it a lot easier to read. (Use the Preview to the right to make sure it looks right.)


#12

You could for instance take the bottom face, and locate the points for the “outer” surface. Then offset this path to the new wall width and create a new face to push-pull up.
As Dan mentions, using push-pull on the vertical wall surfaces won’t work. Think of how you’d do this when modelling by hand.


#13

thank you for helping me
how can i do that by ruby ?


#14

thank mr Dan for helping , so i am trying to use transformation .
when i selected a face i used face.normal to find direction of movement so how to find the perpendicular direction for face if a return of face.normal equal to (0.948683, -0.316228, -0)
i tried to apply transformation to each inner face like in code below but that field with error message "reference to deleted Face "

 **faces.each{|f|  **
**     if f.normal[0] > 0 and f.normal[1] > 0**
**       tr = Geom::Transformation.new([sum , sum , 0])**
**       ent.transform_entities tr ,f **
**     elsif f.normal[0] < 0 and f.normal[1] > 0**
**       tr = Geom::Transformation.new([-sum , sum , 0])**
**       ent.transform_entities tr ,f **
**     elsif f.normal[0] > 0 and f.normal[1] < 0**
**       tr = Geom::Transformation.new([sum , -sum , 0])**
**       ent.transform_entities tr ,f **
**     elsif f.normal[0] < 0 and f.normal[1] < 0**
**       tr = Geom::Transformation.new([-sum , -sum , 0])   **
**       ent.transform_entities tr ,f **

**   else **
**     UI.messagebox "wrong"**
**   end **
**   **
**   }**

#15

Again, please post code correctly in the forum …


(1) In your example we do not know what “sum” is.

(2) You do not transform the entire face, you apply the transformation to the face’s vertices.
See the code example here …


#16

i tried to transform vertices so i found new edge appears on faces like in image

this my code

    mod = Sketchup.active_model # Open model
    ent = mod.entities # All entities in model
    sel = mod.selection # Current selection
    faces = sel[0].entities.grep Sketchup::Face 
    vertices = [] 
    normals = []
    newpoint = Array.new(3)
    faces.each{|f| 
    if f.normal == [0,0,1] or f.normal == [-0,-0,1] or f.normal == [0,0,-1] or f.normal == [-0,-0,-1] 
      next
    else
      nor = f.normal
      nor = nor.to_a.map!{|n|
      if nor.to_a.index(n) == 2
        n.to_m          
      else 
        n.to_m * (0.5).m        #changes only on x and y direction
      end
      }

      f.vertices.each{|e| vertices << e
      normals << nor }
    end
    }
    vertices.each{|v|  
    p = v.position
    p = p.to_a.map{|p| p.to_m}
    i = 0 
    while i < 3 do 
      if i == 2
        newpoint[i] = p[i]
      else
        newpoint[i] = p[i] + normals[vertices.index(v)][i]
      end
      i +=1 
    end

    vect = p.vector_to(newpoint)
    vect = vect.to_a.map{|v| v.m}

    tr = Geom::Transformation.new(vect)
    sel[0].entities.transform_entities tr , v

    }


#17

i tried to transform vertices so i found new edge appears on faces like in image

this my code

 mod = Sketchup.active_model # Open model![t|690x338](upload://d9qk6rNu8EzeEetY9g9Bp6Xsd7w.png) 
    ent = mod.entities # All entities in model
    sel = mod.selection # Current selection
    faces = sel[0].entities.grep Sketchup::Face 
    vertices = [] 
    normals = []
    newpoint = Array.new(3)
    faces.each{|f| 
    if f.normal == [0,0,1] or f.normal == [-0,-0,1] or f.normal == [0,0,-1] or f.normal == [-0,-0,-1] 
      next
    else
      nor = f.normal
      nor = nor.to_a.map!{|n|
      if nor.to_a.index(n) == 2
        n.to_m          
      else 
        n.to_m * (0.5).m        #changes only on x and y direction
      end
      }

      f.vertices.each{|e| vertices << e
      normals << nor }
    end
    }
    vertices.each{|v|  
    p = v.position
    p = p.to_a.map{|p| p.to_m}
    i = 0 
    while i < 3 do 
      if i == 2
        newpoint[i] = p[i]
      else
        newpoint[i] = p[i] + normals[vertices.index(v)][i]
      end
      i +=1 
    end

    vect = p.vector_to(newpoint)
    vect = vect.to_a.map{|v| v.m}

    tr = Geom::Transformation.new(vect)
    sel[0].entities.transform_entities tr , v

    }


#18

I saw your previous post. It is not respectful to flood the topic with duplicate posts.
I am busy and not able to participate further in this discussion.