obtenir les coupes à intervalle regulier d'un objet

Forum destiné aux questions et discussions en français
Forum rules
Règles du forum et informations utiles.

VEUILLEZ LIRE CECI AVANT DE DEMANDER DE L'AIDE
mario52
Veteran
Posts: 4672
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: 7795
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: 4672
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 18 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: 4672
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: 2572
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: 2572
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