Difference between revisions of "Mesh to Part/ru"

From FreeCAD Documentation
Jump to navigation Jump to search
m
(Created page with "Category:Python Code/ru")
(16 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 +
<languages/>
 +
{{docnav|Topological data scripting|Scenegraph}}
 +
 
== Преобразование Part объектов в Полигиональную сетку ==
 
== Преобразование Part объектов в Полигиональную сетку ==
  
 
Конвертация высоко-уровневых объектов, таких как [[Part Module|формы Part(Деталей)]] в простые объекты такие как  [[Mesh Module|полигиональные сетки]] это довольно простая операция, когда все грани Детали разбиваются на треугольники . Результат этой триангуляции  затем используется для построения сетки:
 
Конвертация высоко-уровневых объектов, таких как [[Part Module|формы Part(Деталей)]] в простые объекты такие как  [[Mesh Module|полигиональные сетки]] это довольно простая операция, когда все грани Детали разбиваются на треугольники . Результат этой триангуляции  затем используется для построения сетки:
 
+
{{Code|code=
#let's assume our document contains one part object
+
#let's assume our document contains one part object
import Mesh
+
import Mesh
faces = []
+
faces = []
shape = FreeCAD.ActiveDocument.ActiveObject.Shape
+
shape = FreeCAD.ActiveDocument.ActiveObject.Shape
triangles = shape.tessellate(1) # the number represents the precision of the tessellation)
+
triangles = shape.tessellate(1) # the number represents the precision of the tessellation)
for tri in triangles[1]:
+
for tri in triangles[1]:
    face = []
+
    face = []
    for i in range(3):
+
    for i in range(3):
        vindex = tri[i]
+
        vindex = tri[i]
        face.append(triangles[0][vindex])
+
        face.append(triangles[0][vindex])
    faces.append(face)
+
    faces.append(face)
m = Mesh.Mesh(faces)
+
m = Mesh.Mesh(faces)
Mesh.show(m)
+
Mesh.show(m)
 
+
}}
 
Иногда, триангуляция определенной грани, предлагаемая OpenCascade очень уродлива. Если грань Если грань принадлежит к множеству многоугольников и не содержит любых отверстий или других обрезанных кривых, вы также можете создать сетку по вашему усмотрению:
 
Иногда, триангуляция определенной грани, предлагаемая OpenCascade очень уродлива. Если грань Если грань принадлежит к множеству многоугольников и не содержит любых отверстий или других обрезанных кривых, вы также можете создать сетку по вашему усмотрению:
 +
{{Code|code=
 +
import Mesh
 +
def makeMeshFromFace(u,v,face):
 +
(a,b,c,d)=face.ParameterRange
 +
pts=[]
 +
for j in range(v):
 +
for i in range(u):
 +
s=1.0/(u-1)*(i*b+(u-1-i)*a)
 +
t=1.0/(v-1)*(j*d+(v-1-j)*c)
 +
pts.append(face.valueAt(s,t))
  
import Mesh
+
mesh=Mesh.Mesh()
def makeMeshFromFace(u,v,face):
+
for j in range(v-1):
(a,b,c,d)=face.ParameterRange
+
for i in range(u-1):
pts=[]
+
mesh.addFacet(pts[u*j+i],pts[u*j+i+1],pts[u*(j+1)+i])
for j in range(v):
+
mesh.addFacet(pts[u*(j+1)+i],pts[u*j+i+1],pts[u*(j+1)+i+1])
for i in range(u):
 
s=1.0/(u-1)*(i*b+(u-1-i)*a)
 
t=1.0/(v-1)*(j*d+(v-1-j)*c)
 
pts.append(face.valueAt(s,t))
 
 
mesh=Mesh.Mesh()
 
for j in range(v-1):
 
for i in range(u-1):
 
mesh.addFacet(pts[u*j+i],pts[u*j+i+1],pts[u*(j+1)+i])
 
mesh.addFacet(pts[u*(j+1)+i],pts[u*j+i+1],pts[u*(j+1)+i+1])
 
 
return mesh
 
  
 +
return mesh
 +
}}
 
== Преобразование Сетки в Part объект ==
 
== Преобразование Сетки в Part объект ==
  
Line 44: Line 47:
  
 
В настоящее время FreeCAD предлагает два метода для преобразования Полигиональной Сетки в Деталь. Первый метод прост, это прямое преобразование, без какой либо оптимизации:
 
В настоящее время FreeCAD предлагает два метода для преобразования Полигиональной Сетки в Деталь. Первый метод прост, это прямое преобразование, без какой либо оптимизации:
 +
{{Code|code=
 +
import Mesh,Part
 +
mesh = Mesh.createTorus()
 +
shape = Part.Shape()
 +
shape.makeShapeFromMesh(mesh.Topology,0.05) # the second arg is the tolerance for sewing
 +
solid = Part.makeSolid(shape)
 +
Part.show(solid)
 +
 +
}}
 +
Второй метод позволяет учитывать какие грани сетки компланарны, когда угол между ними принимает определенное значение. Это позволяет строить формы попроще:
 +
{{Code|code=
 +
# let's assume our document contains one Mesh object
 +
import Mesh,Part,MeshPart
 +
faces = []
 +
mesh = App.ActiveDocument.ActiveObject.Mesh
 +
segments = mesh.getPlanes(0.00001) # use rather strict tolerance here
 +
 +
for i in segments:
 +
  if len(i) > 0:
 +
    # a segment can have inner holes
 +
    wires = MeshPart.wireFromSegment(mesh, i)
 +
    # we assume that the exterior boundary is that one with the biggest bounding box
 +
    if len(wires) > 0:
 +
        ext=None
 +
        max_length=0
 +
        for i in wires:
 +
          if i.BoundBox.DiagonalLength > max_length:
 +
              max_length = i.BoundBox.DiagonalLength
 +
              ext = i
  
import Mesh,Part
+
        wires.remove(ext)
mesh = Mesh.createTorus()
+
        # all interior wires mark a hole and must reverse their orientation, otherwise Part.Face fails
shape = Part.Shape()
+
        for i in wires:
shape.makeShapeFromMesh(mesh.Topology,0.05) # the second arg is the tolerance for sewing
+
          i.reverse()
solid = Part.makeSolid(shape)
 
Part.show(solid)
 
  
Второй метод позволяет учитывать какие грани сетки компланарны, когда угол между ними принимает определенное значение. Это позволяет строить формы попроще:
+
        # make sure that the exterior wires comes as first in the list
 +
        wires.insert(0, ext)
 +
        faces.append(Part.Face(wires))
  
# let's assume our document contains one Mesh object
+
shell=Part.Compound(faces)
import Mesh,Part,MeshPart
+
Part.show(shell)
faces = []
+
#solid = Part.Solid(Part.Shell(faces))
mesh = App.ActiveDocument.ActiveObject.Mesh
+
#Part.show(solid)
segments = mesh.getPlanes(0.00001) # use rather strict tolerance here
 
 
for i in segments:
 
  if len(i) > 0:
 
      # a segment can have inner holes
 
      wires = MeshPart.wireFromSegment(mesh, i)
 
      # we assume that the exterior boundary is that one with the biggest bounding box
 
      if len(wires) > 0:
 
        ext=None
 
        max_length=0
 
        for i in wires:
 
            if i.BoundBox.DiagonalLength > max_length:
 
              max_length = i.BoundBox.DiagonalLength
 
              ext = i
 
 
        wires.remove(ext)
 
        # all interior wires mark a hole and must reverse their orientation, otherwise Part.Face fails
 
        for i in wires:
 
            i.reverse()
 
 
        # make sure that the exterior wires comes as first in the lsit
 
        wires.insert(0, ext)
 
        faces.append(Part.Face(wires))
 
 
shell=Part.Compound(faces)
 
Part.show(shell)
 
#solid = Part.Solid(Part.Shell(faces))
 
#Part.show(solid)
 
  
 +
}}
 
{{docnav/ru|Topological data scripting/ru|Scenegraph/ru}}
 
{{docnav/ru|Topological data scripting/ru|Scenegraph/ru}}
  
{{languages/ru | {{en|Mesh to Part}} {{es|Mesh to Part/es}} {{fr|Mesh to Part/fr}} {{it|Mesh to Part/it}} {{se|Mesh to Part/se}} }}
+
{{Userdocnavi}}
  
 
[[Category:Poweruser Documentation/ru]]
 
[[Category:Poweruser Documentation/ru]]
 +
 +
[[Category:Python Code/ru]]

Revision as of 09:16, 4 April 2019

Other languages:
Bahasa Indonesia • ‎Deutsch • ‎English • ‎Türkçe • ‎español • ‎français • ‎italiano • ‎română • ‎svenska • ‎čeština • ‎русский • ‎日本語

Преобразование Part объектов в Полигиональную сетку

Конвертация высоко-уровневых объектов, таких как формы Part(Деталей) в простые объекты такие как полигиональные сетки это довольно простая операция, когда все грани Детали разбиваются на треугольники . Результат этой триангуляции затем используется для построения сетки:

#let's assume our document contains one part object
import Mesh
faces = []
shape = FreeCAD.ActiveDocument.ActiveObject.Shape
triangles = shape.tessellate(1) # the number represents the precision of the tessellation)
for tri in triangles[1]:
    face = []
    for i in range(3):
        vindex = tri[i]
        face.append(triangles[0][vindex])
    faces.append(face)
m = Mesh.Mesh(faces)
Mesh.show(m)

Иногда, триангуляция определенной грани, предлагаемая OpenCascade очень уродлива. Если грань Если грань принадлежит к множеству многоугольников и не содержит любых отверстий или других обрезанных кривых, вы также можете создать сетку по вашему усмотрению:

import Mesh
def makeMeshFromFace(u,v,face):
	(a,b,c,d)=face.ParameterRange
	pts=[]
	for j in range(v):
		for i in range(u):
			s=1.0/(u-1)*(i*b+(u-1-i)*a)
			t=1.0/(v-1)*(j*d+(v-1-j)*c)
			pts.append(face.valueAt(s,t))

	mesh=Mesh.Mesh()
	for j in range(v-1):
		for i in range(u-1):
			mesh.addFacet(pts[u*j+i],pts[u*j+i+1],pts[u*(j+1)+i])
			mesh.addFacet(pts[u*(j+1)+i],pts[u*j+i+1],pts[u*(j+1)+i+1])

	return mesh

Преобразование Сетки в Part объект

Преобразование полигиональной сетки в Деталь черезвычайно важная операция в работе CAD, потому что очень часто вы получаете, от других людей или на выходе из других приложений, 3D данные в полигиональном виде. Сетки это очень практичны для представления геометрии свободной формы и больших визуальных сцен, так как они очень легковесны, но в CAD мы в основном предпочитаем высокоуровневые объекты, которые несут гораздо больше информации, таких как идеии твердых тел, или грани созданой из кривых а не труегольников.

Преобразование сетки в высокоуровневый объект (занимается в FreeCAD Модуль Деталей) это не простая операция. Сетки могут состоять из тысяч треугольников (например когда, сгенерированы 3D сканером), и телом состоящим из того же числа граней, будет черезвычайно сложно управлять. Поэтому вы хотите оптимизировать объект при преобразовании.

В настоящее время FreeCAD предлагает два метода для преобразования Полигиональной Сетки в Деталь. Первый метод прост, это прямое преобразование, без какой либо оптимизации:

import Mesh,Part
mesh = Mesh.createTorus()
shape = Part.Shape()
shape.makeShapeFromMesh(mesh.Topology,0.05) # the second arg is the tolerance for sewing
solid = Part.makeSolid(shape)
Part.show(solid)

Второй метод позволяет учитывать какие грани сетки компланарны, когда угол между ними принимает определенное значение. Это позволяет строить формы попроще:

# let's assume our document contains one Mesh object
import Mesh,Part,MeshPart
faces = []
mesh = App.ActiveDocument.ActiveObject.Mesh
segments = mesh.getPlanes(0.00001) # use rather strict tolerance here
 
for i in segments:
  if len(i) > 0:
     # a segment can have inner holes
     wires = MeshPart.wireFromSegment(mesh, i)
     # we assume that the exterior boundary is that one with the biggest bounding box
     if len(wires) > 0:
        ext=None
        max_length=0
        for i in wires:
           if i.BoundBox.DiagonalLength > max_length:
              max_length = i.BoundBox.DiagonalLength
              ext = i

        wires.remove(ext)
        # all interior wires mark a hole and must reverse their orientation, otherwise Part.Face fails
        for i in wires:
           i.reverse()

        # make sure that the exterior wires comes as first in the list
        wires.insert(0, ext)
        faces.append(Part.Face(wires))

shell=Part.Compound(faces)
Part.show(shell)
#solid = Part.Solid(Part.Shell(faces))
#Part.show(solid)