obtenir les coupes à intervalle regulier d'un objet

Forum destiné aux questions et discussions en français
Forum rules
Be nice to others! Read the FreeCAD code of conduct!
mario52
Veteran
Posts: 4673
Joined: Wed May 16, 2012 2:13 pm

Re: obtenir les coupes à intervalle regulier d'un objet

Post by mario52 »

Bonjour patrick_83

un petit exemple pour créer les plan (les coupes sont pour vous):

sélectionnez un objet, les plans se font dans l'axe Z en utilisant la hauteur du boudbox

Code: Select all

# -*- coding: utf-8 -*-    # pour accepter les accents (mais je n'en met pas, trop de problemes)

import FreeCAD
import Part
import Part,PartGui
import Draft

from FreeCAD import Base
#App.ActiveDocument.addObject("Part::Plane","Plane")
#App.ActiveDocument.Plane.Length=100.00
#App.ActiveDocument.Plane.Width=100.00
#App.ActiveDocument.Plane.Placement=Base.Placement(Base.Vector(-50.00,-50.00,0.00),Base.Rotation(0.00,0.00,0.00,1.00))
#App.ActiveDocument.Plane.Label='Plan'
#App.ActiveDocument.recompute()
#
#obj = Draft.makeArray(FreeCAD.ActiveDocument.Plane,FreeCAD.Vector(1,0,0),FreeCAD.Vector(0,1,0),2,2)
#Draft.autogroup(obj)
#FreeCAD.ActiveDocument.recompute()
#
#FreeCAD.getDocument("cone").getObject("Array").NumberX = 1
#FreeCAD.getDocument("cone").getObject("Array").NumberY = 1
#FreeCAD.getDocument("cone").getObject("Array").NumberZ = 10
#FreeCAD.getDocument("cone").getObject("Array").IntervalZ = (0, 0, 50)
#App.activeDocument().addObject("Part::MultiCommon","Common")
#App.activeDocument().Common.Shapes = [App.activeDocument().Array,App.activeDocument().Cone,]
#App.ActiveDocument.recompute()


try:
    sel = FreeCADGui.Selection.getSelection()[0]
    #boundBoxLX  = sel.Shape.BoundBox.XLength                                           # Length x boundBox rectangle
    #boundBoxLY  = sel.Shape.BoundBox.YLength                                           # Length y boundBox rectangle
    boundBoxLZ  = sel.Shape.BoundBox.ZLength                                           # Length z boundBox rectangle
    #boundBoxDiag= sel.Shape.BoundBox.DiagonalLength                                    # Diagonal Length boundBox rectangle
    #boundBoxCenter = sel.Shape.BoundBox.Center                                         # BoundBox Center
    
    hauteur = boundBoxLZ
    nombreDePlans = 10
    entreDeux = hauteur/nombreDePlans
    planX = 100
    planY = 100
    ii = 0
    for i in range(nombreDePlans + 1):
        print("Plan_" + str(i))
        plan = App.ActiveDocument.addObject("Part::Plane","Plane")
        plan.Length=100.00
        plan.Width=100.00
        plan.Placement = Base.Placement(Base.Vector(-(planX/2),-(planY/2),ii),Base.Rotation(0.00,0.00,0.00,1.00))
        plan.Label = "Plan_" + str(i)
        ii = (i+1) * entreDeux
    App.ActiveDocument.recompute()
except Exception:
    FreeCAD.Console.PrintError("Selectionnez un objet" + "\n")


PS: pour le code vous pouvez utiliser les balises "code" en cliquant sur le bouton"</>"
GlouGlou wrote: Wed Oct 30, 2019 5:38 pm Image
vous êtes le premier à utiliser les FCIcon Image

mario
Maybe you need a special feature, go into Macros_recipes and Code_snippets, Topological_data_scripting.
My macros on Gist.github here complete macros Wiki and forum.
User avatar
papyblaise
Veteran
Posts: 7864
Joined: Thu Jun 13, 2019 4:28 pm
Location: France

Re: obtenir les coupes à intervalle regulier d'un objet

Post by papyblaise »

où qu'on les trouve ces icons
mario52
Veteran
Posts: 4673
Joined: Wed May 16, 2012 2:13 pm

Re: obtenir les coupes à intervalle regulier d'un objet

Post by mario52 »

Maybe you need a special feature, go into Macros_recipes and Code_snippets, Topological_data_scripting.
My macros on Gist.github here complete macros Wiki and forum.
patrick_83
Posts: 30
Joined: Tue Oct 22, 2019 10:10 am

Re: obtenir les coupes à intervalle regulier d'un objet

Post by patrick_83 »

bonjour,
j'ai réussi à créer une macro pour avoir une section à une position donnée mais je n'arrive pas à la modifier pour obtenir les différentes sections. J' ai des messages d'erreurs quand je rajoute la boucle ( Not enough shape objects linked dans les Common).
j'ai bien essayé d' appliquer la solution utilisée dans https://aero-modelisme.com/conception-a ... n-gratuit/ mais j'ai plein d'erreurs
cone.FCStd
(3.05 KiB) Downloaded 19 times

Code: Select all

import FreeCAD
import Part
import Part,PartGui
from FreeCAD import Base

pas= 50 
h_totale =500
planX = 100
planY = 100
pos = 0

while  pos< h_totale :

	#plan de coupe à pos 
	plan = App.ActiveDocument.addObject("Part::Plane","Plane")
	plan.Length=planX
	plan.Width= planY
	plan.Placement = Base.Placement(Base.Vector(-(planX/2),-(planY/2),pos),Base.Rotation(0.00,0.00,0.00,1.00))
	plan.Label = "Plan_" + str(pos)
	
	#section
	App.activeDocument().addObject("Part::MultiCommon","Common")
	App.activeDocument().Common.Shapes = [App.activeDocument().Plane,App.activeDocument().Cone,]
	pos = pos + pas 
	App.ActiveDocument.recompute()
mario52
Veteran
Posts: 4673
Joined: Wed May 16, 2012 2:13 pm

Re: obtenir les coupes à intervalle regulier d'un objet

Post by mario52 »

Bonjour

vous devez créer autant de clones du cône que de coupes (plans)

mario
Maybe you need a special feature, go into Macros_recipes and Code_snippets, Topological_data_scripting.
My macros on Gist.github here complete macros Wiki and forum.
User avatar
Chris_G
Veteran
Posts: 2579
Joined: Tue Dec 31, 2013 4:10 pm
Location: France
Contact:

Re: obtenir les coupes à intervalle regulier d'un objet

Post by Chris_G »

Ceci devrait mieux fonctionner :

Code: Select all

import FreeCAD
import Part
import Part,PartGui
from FreeCAD import Base

pas= 50 
h_totale =500
planX = 100
planY = 100
pos = 0

while  pos< h_totale :

	#plan de coupe à pos 
	plan = App.ActiveDocument.addObject("Part::Plane","Plane")
	plan.Length=planX
	plan.Width= planY
	plan.Placement = Base.Placement(Base.Vector(-(planX/2),-(planY/2),pos),Base.Rotation(0.00,0.00,0.00,1.00))
	plan.Label = "Plan_" + str(pos)
	
	#section
	com = App.ActiveDocument.addObject("Part::MultiCommon","Common")
	com.Shapes = [plan, App.ActiveDocument.Cone,]
	pos = pos + pas 
	App.ActiveDocument.recompute()

L'origine du problème se situe dans la façon d'accéder aux objets :

Code: Select all

App.ActiveDocument.addObject("Part::Plane","myPlane")
Ici, on créé un objet Part::Plane que l'on souhaite baptiser myPlane
FreeCAD va alors créer l'objet et le baptiser comme demandé, si le nom est disponible, sinon, il y ajoute un numéro.
Essayez ceci :

Code: Select all

for i in range(5):
	obj = App.ActiveDocument.addObject("Part::Plane","myPlane")
	print(obj.Name, obj.Label)
vous obtiendrez quelque chose comme ceci :

Code: Select all

myPlane myPlane
myPlane001 myPlane001
myPlane002 myPlane002
myPlane003 myPlane003
myPlane004 myPlane004
On a donc pas de garantie que l'objet a bien été baptisé comme demandé.
Donc quand on a ceci dans une boucle:

Code: Select all

App.activeDocument().addObject("Part::MultiCommon","Common")
App.activeDocument().Common.Shapes = [App.activeDocument().Plane,App.activeDocument().Cone,]
On tombe sur un problème :

Code: Select all

App.activeDocument().addObject("Part::MultiCommon","Common") # créé successivement Common, Common001, Common002, Common003, etc
App.activeDocument().Common.... # on accède toujours au même objet appelé Common (c.a.d celui créé au premier tour de boucle) 
La meilleure solution est donc de ne pas accéder à l'objet par son nom, mais de garder une référence à cet objet quand on le créé :

Code: Select all

mon_objet = App.activeDocument().addObject("Part::MultiCommon","Common")
mon_objet.Shapes = [mon_plan, mon_cone,]
patrick_83
Posts: 30
Joined: Tue Oct 22, 2019 10:10 am

Re: obtenir les coupes à intervalle regulier d'un objet

Post by patrick_83 »

bonjour,
je progresse, par contre je suis toujours obligé de donner le nom de l'objet à découper ("Volume") dans la macro ou le renommer dans l'arbre de construction et de le cacher manuellement pour voir le résultat. Comment éviter cela ?

Code: Select all

# -*- coding: utf-8 -*-
# decoupe d'un objet " Volume"
import FreeCAD
import DraftTools
import Draft
import Part
from FreeCAD import Base

FreeCAD.ActiveDocument.recompute()
Obj_Doc = FreeCAD.activeDocument
	
# planX et planY : dim plan coupe
planX = 100
planY = 100
hauteur = 500
pas = 50
pos= 0
i=0

Obj_solide = FreeCAD.ActiveDocument.getObjectsByLabel("Volume")


while pos<= hauteur :
	# creation du plan de coupe
	pl = FreeCAD.Placement()
	pl.Rotation.Q = (0.0,0.0,0.0,1.0)
	pl.Base = FreeCAD.Vector(-0.5*planX,-0.5*planY,0.0)
	Plan_coupe = Draft.makeRectangle(length=planX, height=planY, placement=pl, face=True,support=None)
	Plan_coupe.Placement = App.Placement(App.Vector(-planX/2,- planY/2,pos),App.Rotation(App.Vector(0,0,1),0))
	Plan_coupe.Label = "Plan_"+str(pos)
	App.ActiveDocument.recompute()
	
	#creation des sections
	Obj_clone_solid = Draft.clone(Obj_solide)
	Obj_clone_solid.Label = "solide_"+str(pos)
	
	Obj_Plan_coupe = FreeCAD.ActiveDocument.getObjectsByLabel("Plan_"+str(pos))
	Obj_solidpos = FreeCAD.ActiveDocument.getObjectsByLabel("solide_"+str(pos))
	
	FreeCAD.ActiveDocument.addObject("Part::MultiCommon","Common"+str(pos))
	Obj_intersect = FreeCAD.ActiveDocument.getObject("Common"+str(pos))
	Obj_intersect.Shapes = [Obj_solidpos[0],Obj_Plan_coupe[0],]
	Obj_intersect.Label = ("Section_"+str(pos))
	FreeCAD.ActiveDocument.recompute()

	i=i+1
	pos = pos + pas
User avatar
Chris_G
Veteran
Posts: 2579
Joined: Tue Dec 31, 2013 4:10 pm
Location: France
Contact:

Re: obtenir les coupes à intervalle regulier d'un objet

Post by Chris_G »

Vous pouvez utiliser le système de sélection de FreeCAD :

Code: Select all

import FreeCADGui
Obj_solide = FreeCADGui.Selection.getSelection()[0]
Obj_solide.ViewObject.hide()
patrick_83
Posts: 30
Joined: Tue Oct 22, 2019 10:10 am

Re: obtenir les coupes à intervalle regulier d'un objet

Post by patrick_83 »

Merci à tous ,cela fonctionne et en mettant bout à bout tous les conseils cela donne cela

Code: Select all

# -*- coding: utf-8 -*-
# decoupe d'un objet 
import FreeCAD
import DraftTools
import Draft
import Part
import FreeCADGui
from FreeCAD import Base
try:
	# selection  de l'objet, caché, calcul de la hauteur
	Obj_solide = FreeCADGui.Selection.getSelection()[0]
	Obj_solide.ViewObject.hide()
	boundBoxLZ  = Obj_solide.Shape.BoundBox.ZLength   
	hauteur = boundBoxLZ		
	FreeCAD.ActiveDocument.recompute()
	Obj_Doc = FreeCAD.activeDocument
	
	# planX et planY : dim plan coupe et intervalle
	planX = 100
	planY = 100
	pas = 50
	
	pos= 0
	i=0
		
	while pos<= hauteur :
		# creation du plan de coupe
		pl = FreeCAD.Placement()
		pl.Rotation.Q = (0.0,0.0,0.0,1.0)
		pl.Base = FreeCAD.Vector(-0.5*planX,-0.5*planY,0.0)
		Plan_coupe = Draft.makeRectangle(length=planX, height=planY, placement=pl, face=True,support=None)
		Plan_coupe.Placement = App.Placement(App.Vector(-planX/2,- planY/2,pos),App.Rotation(App.Vector(0,0,1),0))
		Plan_coupe.Label = "Plan_"+str(pos)
		App.ActiveDocument.recompute()
		
		#creation des sections
		Obj_clone_solid = Draft.clone(Obj_solide)
		Obj_clone_solid.Label = "solide_"+str(pos)
		Obj_Plan_coupe = FreeCAD.ActiveDocument.getObjectsByLabel("Plan_"+str(pos))
		Obj_solidpos = FreeCAD.ActiveDocument.getObjectsByLabel("solide_"+str(pos))
		FreeCAD.ActiveDocument.addObject("Part::MultiCommon","Common"+str(pos))
		Obj_intersect = FreeCAD.ActiveDocument.getObject("Common"+str(pos))
		Obj_intersect.Shapes = [Obj_solidpos[0],Obj_Plan_coupe[0],]
		Obj_intersect.Label = ("Section_"+str(pos))
		FreeCAD.ActiveDocument.recompute()
	
		i=i+1
		pos = pos + pas

except Exception:
	FreeCAD.Console.PrintError("Selectionnez un objet" + "\n")
Post Reply