Line drawing function/ro: Difference between revisions

From FreeCAD Documentation
(Created page with "Apoi, faceți dublu clic în vizualizarea 3D, și bingo, aici este linia noastră! Pentru a face din nou, doar tastați '''exercise.line()''' din nou, și din nou și din nou...")
(Updating to match new version of source page)
(13 intermediate revisions by 2 users not shown)
Line 1: Line 1:
<languages/>
<languages/>

{{TOCright}}

==Introduction==

<div class="mw-translate-fuzzy">
Această pagină arată modul în care se poate construi cu ușurință o funcționalitatea avansată în Python. În acest exercițiu, vom construi un nou instrument care atrage o linie. Acest instrument poate fi apoi legat la o comandă FreeCAD și această comandă poate fi apelată de orice element al interfeței, cum ar fi un element de meniu sau un buton din bara de unelte.
Această pagină arată modul în care se poate construi cu ușurință o funcționalitatea avansată în Python. În acest exercițiu, vom construi un nou instrument care atrage o linie. Acest instrument poate fi apoi legat la o comandă FreeCAD și această comandă poate fi apelată de orice element al interfeței, cum ar fi un element de meniu sau un buton din bara de unelte.
</div>


<div class="mw-translate-fuzzy">
==Scriptul Principal==
==Scriptul Principal==
Mai întâi vom scrie un script care conține toate funcționalitățile noastre. Apoi, vom salva acest lucru într-un fișier și îl vom importa în FreeCAD, astfel încât toate clasele și funcțiile pe care le scriem vor fi disponibile pentru FreeCAD. Deci, lansați editorul de text preferat și tastați următoarele rânduri:
Mai întâi vom scrie un script care conține toate funcționalitățile noastre. Apoi, vom salva acest lucru într-un fișier și îl vom importa în FreeCAD, astfel încât toate clasele și funcțiile pe care le scriem vor fi disponibile pentru FreeCAD. Deci, lansați editorul de text preferat și tastați următoarele rânduri:
</div>

First we will write a script containing all our functionality. Then we will save this in a file and import it in FreeCAD to make all its classes and functions available. Launch your favorite code editor and type the following lines:

{{Code|code=
{{Code|code=
import FreeCADGui, Part
import FreeCADGui, Part
from pivy.coin import *
from pivy.coin import *

class line:
class line:

"this class will create a line after the user clicked 2 points on the screen"
"""This class will create a line after the user clicked 2 points on the screen"""

def __init__(self):
def __init__(self):
self.view = FreeCADGui.ActiveDocument.ActiveView
self.view = FreeCADGui.ActiveDocument.ActiveView
self.stack = []
self.stack = []
self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(),self.getpoint)
self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(), self.getpoint)


def getpoint(self,event_cb):
def getpoint(self, event_cb):
event = event_cb.getEvent()
event = event_cb.getEvent()
if event.getState() == SoMouseButtonEvent.DOWN:
if event.getState() == SoMouseButtonEvent.DOWN:
pos = event.getPosition()
pos = event.getPosition()
point = self.view.getPoint(pos[0],pos[1])
point = self.view.getPoint(pos[0], pos[1])
self.stack.append(point)
self.stack.append(point)
if len(self.stack) == 2:
if len(self.stack) == 2:
l = Part.Line(self.stack[0],self.stack[1])
l = Part.LineSegment(self.stack[0], self.stack[1])
shape = l.toShape()
shape = l.toShape()
Part.show(shape)
Part.show(shape)
self.view.removeEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(),self.callback)
self.view.removeEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(), self.callback)
}}
}}

=== Explicații detaliate ===
[[#top|top]]

== Explicații detaliate ==

{{Code|code=
{{Code|code=
import Part, FreeCADGui
import Part, FreeCADGui
from pivy.coin import *
from pivy.coin import *
}}
}}

<div class="mw-translate-fuzzy">
În Python, atunci când doriți să utilizați funcții dintr-un alt modul, trebuie să-l importați. În cazul nostru, vom avea nevoie de funcții de la [[Part Module]], pentru crearea liniei și de la modulul Gui (FreeCADGui), pentru a accesa vizualizarea 3D. De asemenea, avem nevoie de conținutul complet al bibliotecii de monede, astfel încât să putem folosi direct toate obiectele precum coin, SoMouseButtonEvent, (eveniment mouse) etc ...
În Python, atunci când doriți să utilizați funcții dintr-un alt modul, trebuie să-l importați. În cazul nostru, vom avea nevoie de funcții de la [[Part Module]], pentru crearea liniei și de la modulul Gui (FreeCADGui), pentru a accesa vizualizarea 3D. De asemenea, avem nevoie de conținutul complet al bibliotecii de monede, astfel încât să putem folosi direct toate obiectele precum coin, SoMouseButtonEvent, (eveniment mouse) etc ...
</div>

{{Code|code=
{{Code|code=
class line:
class line:
}}
}}

Aici definim clasa noastră principală. De ce folosim o clasă și nu o funcție? Motivul este că avem nevoie ca instrumentul nostru să rămână "în viață" în timp ce așteptăm ca utilizatorul să facă clic pe ecran. O funcție se termină atunci când sarcina sa a fost făcută, dar un obiect (o clasă definește un obiect) rămâne în viață până când este distrus.
Aici definim clasa noastră principală. De ce folosim o clasă și nu o funcție? Motivul este că avem nevoie ca instrumentul nostru să rămână "în viață" în timp ce așteptăm ca utilizatorul să facă clic pe ecran. O funcție se termină atunci când sarcina sa a fost făcută, dar un obiect (o clasă definește un obiect) rămâne în viață până când este distrus.

{{Code|code=
{{Code|code=
"this class will create a line after the user clicked 2 points on the screen"
"""This class will create a line after the user clicked 2 points on the screen"""
}}
}}

<div class="mw-translate-fuzzy">
În Python, fiecare clasă sau funcție poate avea o descriere. Acest lucru este util în particular în FreeCAD, deoarece atunci când veți apela acea clasă în interpret, descrierea va fi afișată ca o sugestie .
În Python, fiecare clasă sau funcție poate avea o descriere. Acest lucru este util în particular în FreeCAD, deoarece atunci când veți apela acea clasă în interpret, descrierea va fi afișată ca o sugestie .
</div>

{{Code|code=
{{Code|code=
def __init__(self):
def __init__(self):
}}
}}

<div class="mw-translate-fuzzy">
Clasele Python întotdeauna trebuie să conțină o funcție __init__function, care este executată atunci când clasa este apelată să creeze un obiect. Deci, vom pune aici tot ce vrem să se întâmple atunci când instrumentul nostru de linie începe(este apelat).
Clasele Python întotdeauna trebuie să conțină o funcție __init__function, care este executată atunci când clasa este apelată să creeze un obiect. Deci, vom pune aici tot ce vrem să se întâmple atunci când instrumentul nostru de linie începe(este apelat).
</div>

{{Code|code=
{{Code|code=
self.view = FreeCADGui.ActiveDocument.ActiveView
self.view = FreeCADGui.ActiveDocument.ActiveView
}}
}}

<div class="mw-translate-fuzzy">
Într-o clasă, de obicei, este de dorit să adăugați "self" înaintea unui nume de variabilă, astfel încât să fie ușor accesibilă tuturor funcțiilor din interiorul și din afara clasei respective. Aici vom folosi self.view pentru a accesa și manipula vizualizarea 3D activă.
Într-o clasă, de obicei, este de dorit să adăugați "self" înaintea unui nume de variabilă, astfel încât să fie ușor accesibilă tuturor funcțiilor din interiorul și din afara clasei respective. Aici vom folosi self.view pentru a accesa și manipula vizualizarea 3D activă.
</div>

{{Code|code=
{{Code|code=
self.stack = []
self.stack = []
}}
}}

<div class="mw-translate-fuzzy">
Aici vom crea o listă goală care va conține punctele în 3D trimise de funcția getpoint.
Aici vom crea o listă goală care va conține punctele în 3D trimise de funcția getpoint.
</div>

{{Code|code=
{{Code|code=
self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(),self.getpoint)
self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(), self.getpoint)
}}
}}

<div class="mw-translate-fuzzy">
Acesta este un punct/parte importantă: Deoarece că este vorba de o o scenă [http://www.coin3d.org/ coin3D], FreeCAD folosește mecanismul de apel invers, care permite unei funcții să fie apelată de fiecare dată când se întâmplă un anumit eveniment scenă. În cazul nostru, creăm un apel invers pentru evenimentele [http://doc.coin3d.org/Coin/group__events.html SoMouseButtonEvent] și îl legăm la funcția getpoint. Acum, de fiecare dată când este apăsat sau eliberat un buton mouse-ului, funcția GetPoint va fi executată.
Acesta este un punct/parte importantă: Deoarece că este vorba de o o scenă [http://www.coin3d.org/ coin3D], FreeCAD folosește mecanismul de apel invers, care permite unei funcții să fie apelată de fiecare dată când se întâmplă un anumit eveniment scenă. În cazul nostru, creăm un apel invers pentru evenimentele [http://doc.coin3d.org/Coin/group__events.html SoMouseButtonEvent] și îl legăm la funcția getpoint. Acum, de fiecare dată când este apăsat sau eliberat un buton mouse-ului, funcția GetPoint va fi executată.
</div>


<div class="mw-translate-fuzzy">
Rețineți că există, de asemenea, o alternativă la addEventCallbackPivy() numită addEventCallback() care exclude utilizarea pivy. Dar, din moment ce pivu este o modalitate foarte eficientă și naturală de a accesa orice parte a scenei coin, este mult mai bine să o utilizați cât de mult puteți!
Rețineți că există, de asemenea, o alternativă la addEventCallbackPivy() numită addEventCallback() care exclude utilizarea pivy. Dar, din moment ce pivu este o modalitate foarte eficientă și naturală de a accesa orice parte a scenei coin, este mult mai bine să o utilizați cât de mult puteți!
</div>

[[#top|top]]

{{Code|code=
{{Code|code=
def getpoint(self,event_cb):
def getpoint(self, event_cb):
}}
}}

<div class="mw-translate-fuzzy">
Acum definim funcția GetPoint, care va fi executată atunci când un buton al mouse-ului este apăsat într-o vizualizare 3D. Această funcție va primi un argument, pe care îl vom numi event_cb. De la acest apel al evenimentului, putem accesa obiectul eveniment, care conține mai multe informații -mai multe informații pe această pagină (modul info[[Code_snippets#Observing_mouse_events_in_the_3D_viewer_via_Python|here]]).
Acum definim funcția GetPoint, care va fi executată atunci când un buton al mouse-ului este apăsat într-o vizualizare 3D. Această funcție va primi un argument, pe care îl vom numi event_cb. De la acest apel al evenimentului, putem accesa obiectul eveniment, care conține mai multe informații -mai multe informații pe această pagină (modul info[[Code_snippets#Observing_mouse_events_in_the_3D_viewer_via_Python|here]]).
</div>

{{Code|code=
{{Code|code=
if event.getState() == SoMouseButtonEvent.DOWN:
if event.getState() == SoMouseButtonEvent.DOWN:
}}
}}

<div class="mw-translate-fuzzy">
Funcția GetPoint va fi apelată când un buton al mouse-ului este apăsat sau eliberat. Dar vrem să alegem un punct 3D numai atunci când este presat (altfel am obține două puncte foarte aproape unul de celălalt). Așa că trebuie să verificăm asta
Funcția GetPoint va fi apelată când un buton al mouse-ului este apăsat sau eliberat. Dar vrem să alegem un punct 3D numai atunci când este presat (altfel am obține două puncte foarte aproape unul de celălalt). Așa că trebuie să verificăm asta
</div>

{{Code|code=
{{Code|code=
pos = event.getPosition()
pos = event.getPosition()
}}
}}

<div class="mw-translate-fuzzy">
Aici găsim coordonatele cursorului mouse-ului pe ecran
Aici găsim coordonatele cursorului mouse-ului pe ecran
</div>

{{Code|code=
{{Code|code=
point = self.view.getPoint(pos[0],pos[1])
point = self.view.getPoint(pos[0], pos[1])
}}
}}

<div class="mw-translate-fuzzy">
Această funcție ne dă un vector FreeCAD (x, y, z) ale punctului care se află pe planul focal, chiar sub cursorul mouse-ului. Dacă vă aflați într-o vizualizare a camerei foto, imaginați-vă camera trece prin cursorul mouse-ului și atinge planul focal. Acesta este punctul nostru 3D. Dacă suntem în vedere ortogonală, raza este paralelă cu direcția de vizualizare.
Această funcție ne dă un vector FreeCAD (x, y, z) ale punctului care se află pe planul focal, chiar sub cursorul mouse-ului. Dacă vă aflați într-o vizualizare a camerei foto, imaginați-vă camera trece prin cursorul mouse-ului și atinge planul focal. Acesta este punctul nostru 3D. Dacă suntem în vedere ortogonală, raza este paralelă cu direcția de vizualizare.
</div>

{{Code|code=
{{Code|code=
self.stack.append(point)
self.stack.append(point)
}}
}}

<div class="mw-translate-fuzzy">
Noi adăugăm elementul nostru nou în stivă/morman
Noi adăugăm elementul nostru nou în stivă/morman
</div>

{{Code|code=
{{Code|code=
if len(self.stack) == 2:
if len(self.stack) == 2:
}}
}}

Avem toate punctele necesare? dacă da, atunci să tragem linia!
Avem toate punctele necesare? dacă da, atunci să tragem linia!

{{Code|code=
{{Code|code=
l = Part.Line(self.stack[0],self.stack[1])
l = Part.LineSegment(self.stack[0], self.stack[1])
}}
}}

<div class="mw-translate-fuzzy">
Aici folosim funcția line() din [[Part Module]] care a creat o linie din două vectori FreeCAD. Tot ceea ce creăm și modificăm în interiorul modulului Part, rămâne în modulul Part. Deci, până acum, am creat o piesă tip linie. Nu este legat de niciun obiect al documentului nostru activ, deci nu apare nimic pe ecran.
Aici folosim funcția line() din [[Part Module]] care a creat o linie din două vectori FreeCAD. Tot ceea ce creăm și modificăm în interiorul modulului Part, rămâne în modulul Part. Deci, până acum, am creat o piesă tip linie. Nu este legat de niciun obiect al documentului nostru activ, deci nu apare nimic pe ecran.
</div>

{{Code|code=
{{Code|code=
shape = l.toShape()
shape = l.toShape()
}}
}}

<div class="mw-translate-fuzzy">
Documentul FreeCAD poate accepta decât forme din modulul Part Module. Formele sunt cel mai generic tip al Part Module. Deci, trebuie să convertim linia noastră într-o formă înainte de a o adăuga la document.
Documentul FreeCAD poate accepta decât forme din modulul Part Module. Formele sunt cel mai generic tip al Part Module. Deci, trebuie să convertim linia noastră într-o formă înainte de a o adăuga la document.
</div>

{{Code|code=
{{Code|code=
Part.show(shape)
Part.show(shape)
}}
}}

<div class="mw-translate-fuzzy">
Modulul Part Module are o funcție foarte utilă show(), care creează un obiect nou în document și se leagă la o formă. De asemenea, am putea să avem un nou obiect în primul document, apoi să-l legăm manual la formă.
Modulul Part Module are o funcție foarte utilă show(), care creează un obiect nou în document și se leagă la o formă. De asemenea, am putea să avem un nou obiect în primul document, apoi să-l legăm manual la formă.
</div>

{{Code|code=
{{Code|code=
self.view.removeEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(),self.callback)
self.view.removeEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(), self.callback)
}}
}}

<div class="mw-translate-fuzzy">
Deoarece am terminat cu linia noastră, să eliminăm mecanismul de apel invers, care consumă cicluri CPU prețioase.
Deoarece am terminat cu linia noastră, să eliminăm mecanismul de apel invers, care consumă cicluri CPU prețioase.
</div>

[[#top|top]]


<div class="mw-translate-fuzzy">
==Testing & Using the script==
==Testing & Using the script==
Acum, hai să salvăm scriptul într-un loc unde interpretul Python de la FreeCAD îl va găsi. Când importați module, interpretorul va căuta în următoarele locuri: căile de instalare python, directorul bin FreeCAD și toate directoarele modulelor FreeCAD. Deci, cea mai bună soluție este să creați un director nou într-unul din FreeCAD [[Installing_more_workbenches | Mod directories]] și să salvați scriptul în el. De exemplu, să facem un director "MyScripts" și să salvăm scriptul nostru ca "exercise.py".
Acum, hai să salvăm scriptul într-un loc unde interpretul Python de la FreeCAD îl va găsi. Când importați module, interpretorul va căuta în următoarele locuri: căile de instalare python, directorul bin FreeCAD și toate directoarele modulelor FreeCAD. Deci, cea mai bună soluție este să creați un director nou într-unul din FreeCAD [[Installing_more_workbenches | Mod directories]] și să salvați scriptul în el. De exemplu, să facem un director "MyScripts" și să salvăm scriptul nostru ca "exercise.py".
</div>


Now let's save our script in a folder where the FreeCAD Python interpreter can find it. When importing modules, the interpreter will look in the following places: the Python installation paths, the FreeCAD {{FileName|bin}} folder, and all FreeCAD {{FileName|Mod}} (module) folders. So the best solution is to create a new folder in one of the {{FileName|Mod}} folders. Let's create a {{FileName|MyScripts}} folder there and save our script in it as {{FileName|exercise.py}}.

<div class="mw-translate-fuzzy">
Acum, totul este gata, să începem FreeCAD, să creăm un nou document și, în interpretorul python, să tastăm:
Acum, totul este gata, să începem FreeCAD, să creăm un nou document și, în interpretorul python, să tastăm:
</div>

{{Code|code=
{{Code|code=
import exercise
import exercise
}}
}}

<div class="mw-translate-fuzzy">
Dacă nu apare niciun mesaj de eroare, înseamnă că scriptul nostru de exerciții '''exercise''' a fost încărcat. Acum îi putem verifica conținutul cu:
Dacă nu apare niciun mesaj de eroare, înseamnă că scriptul nostru de exerciții '''exercise''' a fost încărcat. Acum îi putem verifica conținutul cu:
</div>

{{Code|code=
{{Code|code=
dir(exercise)
dir(exercise)
}}
}}

<div class="mw-translate-fuzzy">
Comanda '''dir()''' este o comandă python încorporată care listează/enumeră conținutul unui modul. Putem vedea că clasa noastră '''class line()''' este aici, așteptându-ne. Acum, să o testăm:
Comanda '''dir()''' este o comandă python încorporată care listează/enumeră conținutul unui modul. Putem vedea că clasa noastră '''class line()''' este aici, așteptându-ne. Acum, să o testăm:
</div>

{{Code|code=
'line' in dir(exercise)
}}

Now let's test it:

{{Code|code=
{{Code|code=
exercise.line()
exercise.line()
}}
}}

<div class="mw-translate-fuzzy">
Apoi, faceți dublu clic în vizualizarea 3D, și bingo, aici este linia noastră! Pentru a face din nou, doar tastați '''exercise.line()''' din nou, și din nou și din nou ... Vă simțiți minunat, nu-i așa?
Apoi, faceți dublu clic în vizualizarea 3D, și bingo, aici este linia noastră! Pentru a face din nou, doar tastați '''exercise.line()''' din nou, și din nou și din nou ... Vă simțiți minunat, nu-i așa?
</div>


[[#top|top]]

<div class="mw-translate-fuzzy">
== Înregistrarea scriptului în interfața FreeCAD ==
== Înregistrarea scriptului în interfața FreeCAD ==
Acum, pentru ca noul nostru instrument de trasat linii să fie foarte cool, ar trebui să aibă un buton pe interfață, deci să nu trebuiescă să tastăm toate acele lucruri de fiecare dată. Cea mai ușoară cale este să ne transformăm noul director MyScripts într-un atelier de lucru complet FreeCAD. Este ușor, tot ce este necesar este să plasați un fișier numit '''InitGui.py''' în directorul MyScripts. InitGui.py va conține instrucțiunile pentru a crea un nou atelier de lucru și va adăuga noul instrument. În plus, va trebui să transformăm un pic codul nostru de exerciții, astfel încât instrumentul line() este recunoscut ca o comandă oficială FreeCAD. Să începem prin a face un fișier InitGui.py și scrieți următorul cod în el:
Acum, pentru ca noul nostru instrument de trasat linii să fie foarte cool, ar trebui să aibă un buton pe interfață, deci să nu trebuiescă să tastăm toate acele lucruri de fiecare dată. Cea mai ușoară cale este să ne transformăm noul director MyScripts într-un atelier de lucru complet FreeCAD. Este ușor, tot ce este necesar este să plasați un fișier numit '''InitGui.py''' în directorul MyScripts. InitGui.py va conține instrucțiunile pentru a crea un nou atelier de lucru și va adăuga noul instrument. În plus, va trebui să transformăm un pic codul nostru de exerciții, astfel încât instrumentul line() este recunoscut ca o comandă oficială FreeCAD. Să începem prin a face un fișier InitGui.py și scrieți următorul cod în el:
</div>

For our new line tool to be really useful, and to avoid having to type all that stuff, it should have a button in the interface. One way to do this is to transform our new {{FileName|MyScripts}} folder into a full FreeCAD workbench. This is easy, all that is needed is to put a file called {{FileName|InitGui.py}} inside the {{FileName|MyScripts}} folder. {{FileName|InitGui.py}} will contain the instructions to create a new workbench, and add our new tool to it. Besides that we will also need to change our exercise code a bit, so the {{incode|line()}} tool is recognized as an official FreeCAD command. Let's start by creating an {{FileName|InitGui.py}} file, and writing the following code in it:

{{Code|code=
{{Code|code=
class MyWorkbench (Workbench):
class MyWorkbench (Workbench):

MenuText = "MyScripts"
MenuText = "MyScripts"
def Initialize(self):

import exercise
def Initialize(self):
commandslist = ["line"]
import exercise
self.appendToolbar("My Scripts",commandslist)
commandslist = ["line"]
self.appendToolbar("My Scripts", commandslist)

Gui.addWorkbench(MyWorkbench())
Gui.addWorkbench(MyWorkbench())
}}
}}
By now, you should already understand the above script by yourself, I think: We create a new class that we call MyWorkbench, we give it a title (MenuText), and we define an Initialize() function that will be executed when the workbench is loaded into FreeCAD. In that function, we load in the contents of our exercise file, and append the FreeCAD commands found inside to a command list. Then, we make a toolbar called "My Scripts" and we assign our commands list to it. Currently, of course, we have only one tool, so our command list contains only one element. Then, once our workbench is ready, we add it to the main interface.


<div class="mw-translate-fuzzy">
But this still won't work, because a FreeCAD command must be formatted in a certain way to work. So we will need to transform a bit our line() tool. Our new exercise.py script will now look like this:
Până acum, ar fi trebuit să fi înțeles deja scriptul de mai sus, mă gândesc eu: Creați o nouă clasă pe care o numiți MyWorkbench. Îi vom da un titlu (MenuText) și vom defini o funcție Initialize() care va fi executată atunci când atelierul de lucru este încărcat în FreeCAD. În această funcție, încărcăm conținutul fișierului de exerciții și adăugăm comenzile FreeCAD găsite în interiorul unei liste de comenzi. Apoi, facem o bară de instrumente numită "Scripturile mele" și îi atribuim comenzile noastre. În prezent, desigur, avem doar un singur instrument, astfel că lista noastră de comenzi conține doar un singur element. Apoi, odată ce atelierul nostru de lucru este gata, îl adăugăm la interfața principală.
</div>

<div class="mw-translate-fuzzy">
Dar acest lucru nu va funcționa, deoarece o comandă FreeCAD trebuie să fie formatată într-un anumit mod de lucru. Deci, va trebui să transformăm puțin instrumentul nostru '''line()'''. Noul nostu script '''exercise.py''' va arăta cam așa:
</div>

{{Code|code=
{{Code|code=
import FreeCADGui, Part
import FreeCADGui, Part
from pivy.coin import *
from pivy.coin import *

class line:
class line:

"this class will create a line after the user clicked 2 points on the screen"
"""This class will create a line after the user clicked 2 points on the screen"""
def Activated(self):

self.view = FreeCADGui.ActiveDocument.ActiveView
def Activated(self):
self.stack = []
self.view = FreeCADGui.ActiveDocument.ActiveView
self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(),self.getpoint)
self.stack = []
def getpoint(self,event_cb):
self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(), self.getpoint)
event = event_cb.getEvent()

if event.getState() == SoMouseButtonEvent.DOWN:
def getpoint(self, event_cb):
pos = event.getPosition()
point = self.view.getPoint(pos[0],pos[1])
event = event_cb.getEvent()
if event.getState() == SoMouseButtonEvent.DOWN:
self.stack.append(point)
pos = event.getPosition()
if len(self.stack) == 2:
l = Part.Line(self.stack[0],self.stack[1])
point = self.view.getPoint(pos[0], pos[1])
shape = l.toShape()
self.stack.append(point)
Part.show(shape)
if len(self.stack) == 2:
l = Part.LineSegment(self.stack[0], self.stack[1])
self.view.removeEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(),self.callback)
shape = l.toShape()
def GetResources(self):
Part.show(shape)
return {'Pixmap' : 'path_to_an_icon/line_icon.png', 'MenuText': 'Line', 'ToolTip': 'Creates a line by clicking 2 points on the screen'}
self.view.removeEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(), self.callback)

def GetResources(self):
return {'Pixmap': 'path_to_an_icon/line_icon.png', 'MenuText': 'Line', 'ToolTip': 'Creates a line by clicking 2 points on the screen'}

FreeCADGui.addCommand('line', line())
FreeCADGui.addCommand('line', line())
}}
}}
What we did here is transform our __init__() function into an Activated() function, because when FreeCAD commands are run, they automatically execute the Activated() function. We also added a GetResources() function, that informs FreeCAD where it can find an icon for the tool, and what will be the name and tooltip of our tool. Any jpg, png or svg image will work as an icon, it can be any size, but it is best to use a size that is close to the final aspect, like 16x16, 24x24 or 32x32.
Then, we add the line() class as an official FreeCAD command with the addCommand() method.


<div class="mw-translate-fuzzy">
That's it, we now just need to restart FreeCAD and we'll have a nice new workbench with our brand new line tool!
Ceea ce am făcut aici? noi am transformat funcția noastră __init__() function într-o funcție '''Activated()''', deoarece atunci când comenzile FreeCAD sunt executate, ele execută automat funcția '''Activated()'''. Am adăugat, de asemenea, o funcție GetResources (), care informează FreeCAD unde poate găsi o pictogramă pentru instrument și care va fi numele și sugestia/indicația instrumentului nostru. Orice imagine jpg, png sau svg va funcționa ca o pictogramă/iconiță, poate fi orice dimensiune, dar este mai bine să utilizați o dimensiune care este aproape de aspectul final, cum ar fi 16x16, 24x24 sau 32x32.
Apoi, adăugăm '''class line()''' ca o comandă oficială FreeCAD cu metoda '''addCommand()'''.
</div>

<div class="mw-translate-fuzzy">
Asta este, vrem să reporniți FreeCAD și vom avea un nou atelier de lucru cu noul nostru instrument linie '''line'''!
</div>

[[#top|top]]


==Deci vrei mai mult?==
==Deci vrei mai mult?==


<div class="mw-translate-fuzzy">
Dacă ți-a plăcut acest exercițiu, de ce să nu încerci să îmbunătățești acest mic instrument? Sunt multe lucruri care pot fi făcute, ca de exemplu:
Dacă ți-a plăcut acest exercițiu, de ce să nu încerci să îmbunătățești acest mic instrument? Sunt multe lucruri care pot fi făcute, ca de exemplu:
* Adăugați comentarii utilizatorilor: până acum am făcut un instrument foarte subțire îmbrăcat, utilizatorul ar putea fi un pic pierdut atunci când îl utilizează. Așadar, am putea adăuga comentarii, spunându-i ce să facă în continuare. De exemplu, puteți emite mesaje către consola FreeCAD. ”Aruncați o privire” în modulul FreeCAD.Console
* Adăugați comentarii utilizatorilor: până acum am făcut un instrument foarte subțire îmbrăcat, utilizatorul ar putea fi un pic pierdut atunci când îl utilizează. Așadar, am putea adăuga comentarii, spunându-i ce să facă în continuare. De exemplu, puteți emite mesaje către consola FreeCAD. ”Aruncați o privire” în modulul FreeCAD.Console
Line 169: Line 310:
* Dați un nume obiectului creat și multe alte lucruri.
* Dați un nume obiectului creat și multe alte lucruri.
Nu ezitați să vă scrieți întrebările sau ideile pe [http://forum.freecadweb.org/ forum]!
Nu ezitați să vă scrieți întrebările sau ideile pe [http://forum.freecadweb.org/ forum]!
</div>


Don't hesitate to ask questions or share ideas on the [https://forum.freecadweb.org/ forum]!
{{docnav|Code snippets|Dialog creation}}


[[#top|top]]
[[Category:Poweruser Documentation/ro]] [[Category:Python Code/ro]]


{{Powerdocnavi{{#translation:}}}}
[[Category:Developer Documentation{{#translation:}}]]
[[Category:Python Code{{#translation:}}]]
{{clear}}
{{clear}}

Revision as of 21:07, 23 August 2020

Introduction

Această pagină arată modul în care se poate construi cu ușurință o funcționalitatea avansată în Python. În acest exercițiu, vom construi un nou instrument care atrage o linie. Acest instrument poate fi apoi legat la o comandă FreeCAD și această comandă poate fi apelată de orice element al interfeței, cum ar fi un element de meniu sau un buton din bara de unelte.

Scriptul Principal

Mai întâi vom scrie un script care conține toate funcționalitățile noastre. Apoi, vom salva acest lucru într-un fișier și îl vom importa în FreeCAD, astfel încât toate clasele și funcțiile pe care le scriem vor fi disponibile pentru FreeCAD. Deci, lansați editorul de text preferat și tastați următoarele rânduri:

First we will write a script containing all our functionality. Then we will save this in a file and import it in FreeCAD to make all its classes and functions available. Launch your favorite code editor and type the following lines:

import FreeCADGui, Part
from pivy.coin import *

class line:

    """This class will create a line after the user clicked 2 points on the screen"""

    def __init__(self):
        self.view = FreeCADGui.ActiveDocument.ActiveView
        self.stack = []
        self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(), self.getpoint)

    def getpoint(self, event_cb):
        event = event_cb.getEvent()
        if event.getState() == SoMouseButtonEvent.DOWN:
            pos = event.getPosition()
            point = self.view.getPoint(pos[0], pos[1])
            self.stack.append(point)
            if len(self.stack) == 2:
                l = Part.LineSegment(self.stack[0], self.stack[1])
                shape = l.toShape()
                Part.show(shape)
                self.view.removeEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(), self.callback)

top

Explicații detaliate

import Part, FreeCADGui
from pivy.coin import *

În Python, atunci când doriți să utilizați funcții dintr-un alt modul, trebuie să-l importați. În cazul nostru, vom avea nevoie de funcții de la Part Module, pentru crearea liniei și de la modulul Gui (FreeCADGui), pentru a accesa vizualizarea 3D. De asemenea, avem nevoie de conținutul complet al bibliotecii de monede, astfel încât să putem folosi direct toate obiectele precum coin, SoMouseButtonEvent, (eveniment mouse) etc ...

class line:

Aici definim clasa noastră principală. De ce folosim o clasă și nu o funcție? Motivul este că avem nevoie ca instrumentul nostru să rămână "în viață" în timp ce așteptăm ca utilizatorul să facă clic pe ecran. O funcție se termină atunci când sarcina sa a fost făcută, dar un obiect (o clasă definește un obiect) rămâne în viață până când este distrus.

"""This class will create a line after the user clicked 2 points on the screen"""

În Python, fiecare clasă sau funcție poate avea o descriere. Acest lucru este util în particular în FreeCAD, deoarece atunci când veți apela acea clasă în interpret, descrierea va fi afișată ca o sugestie .

def __init__(self):

Clasele Python întotdeauna trebuie să conțină o funcție __init__function, care este executată atunci când clasa este apelată să creeze un obiect. Deci, vom pune aici tot ce vrem să se întâmple atunci când instrumentul nostru de linie începe(este apelat).

self.view = FreeCADGui.ActiveDocument.ActiveView

Într-o clasă, de obicei, este de dorit să adăugați "self" înaintea unui nume de variabilă, astfel încât să fie ușor accesibilă tuturor funcțiilor din interiorul și din afara clasei respective. Aici vom folosi self.view pentru a accesa și manipula vizualizarea 3D activă.

self.stack = []

Aici vom crea o listă goală care va conține punctele în 3D trimise de funcția getpoint.

self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(), self.getpoint)

Acesta este un punct/parte importantă: Deoarece că este vorba de o o scenă coin3D, FreeCAD folosește mecanismul de apel invers, care permite unei funcții să fie apelată de fiecare dată când se întâmplă un anumit eveniment scenă. În cazul nostru, creăm un apel invers pentru evenimentele SoMouseButtonEvent și îl legăm la funcția getpoint. Acum, de fiecare dată când este apăsat sau eliberat un buton mouse-ului, funcția GetPoint va fi executată.

Rețineți că există, de asemenea, o alternativă la addEventCallbackPivy() numită addEventCallback() care exclude utilizarea pivy. Dar, din moment ce pivu este o modalitate foarte eficientă și naturală de a accesa orice parte a scenei coin, este mult mai bine să o utilizați cât de mult puteți!

top

def getpoint(self, event_cb):

Acum definim funcția GetPoint, care va fi executată atunci când un buton al mouse-ului este apăsat într-o vizualizare 3D. Această funcție va primi un argument, pe care îl vom numi event_cb. De la acest apel al evenimentului, putem accesa obiectul eveniment, care conține mai multe informații -mai multe informații pe această pagină (modul infohere).

if event.getState() == SoMouseButtonEvent.DOWN:

Funcția GetPoint va fi apelată când un buton al mouse-ului este apăsat sau eliberat. Dar vrem să alegem un punct 3D numai atunci când este presat (altfel am obține două puncte foarte aproape unul de celălalt). Așa că trebuie să verificăm asta

pos = event.getPosition()

Aici găsim coordonatele cursorului mouse-ului pe ecran

point = self.view.getPoint(pos[0], pos[1])

Această funcție ne dă un vector FreeCAD (x, y, z) ale punctului care se află pe planul focal, chiar sub cursorul mouse-ului. Dacă vă aflați într-o vizualizare a camerei foto, imaginați-vă camera trece prin cursorul mouse-ului și atinge planul focal. Acesta este punctul nostru 3D. Dacă suntem în vedere ortogonală, raza este paralelă cu direcția de vizualizare.

self.stack.append(point)

Noi adăugăm elementul nostru nou în stivă/morman

if len(self.stack) == 2:

Avem toate punctele necesare? dacă da, atunci să tragem linia!

l = Part.LineSegment(self.stack[0], self.stack[1])

Aici folosim funcția line() din Part Module care a creat o linie din două vectori FreeCAD. Tot ceea ce creăm și modificăm în interiorul modulului Part, rămâne în modulul Part. Deci, până acum, am creat o piesă tip linie. Nu este legat de niciun obiect al documentului nostru activ, deci nu apare nimic pe ecran.

shape = l.toShape()

Documentul FreeCAD poate accepta decât forme din modulul Part Module. Formele sunt cel mai generic tip al Part Module. Deci, trebuie să convertim linia noastră într-o formă înainte de a o adăuga la document.

Part.show(shape)

Modulul Part Module are o funcție foarte utilă show(), care creează un obiect nou în document și se leagă la o formă. De asemenea, am putea să avem un nou obiect în primul document, apoi să-l legăm manual la formă.

self.view.removeEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(), self.callback)

Deoarece am terminat cu linia noastră, să eliminăm mecanismul de apel invers, care consumă cicluri CPU prețioase.

top

Testing & Using the script

Acum, hai să salvăm scriptul într-un loc unde interpretul Python de la FreeCAD îl va găsi. Când importați module, interpretorul va căuta în următoarele locuri: căile de instalare python, directorul bin FreeCAD și toate directoarele modulelor FreeCAD. Deci, cea mai bună soluție este să creați un director nou într-unul din FreeCAD Mod directories și să salvați scriptul în el. De exemplu, să facem un director "MyScripts" și să salvăm scriptul nostru ca "exercise.py".

Now let's save our script in a folder where the FreeCAD Python interpreter can find it. When importing modules, the interpreter will look in the following places: the Python installation paths, the FreeCAD bin folder, and all FreeCAD Mod (module) folders. So the best solution is to create a new folder in one of the Mod folders. Let's create a MyScripts folder there and save our script in it as exercise.py.

Acum, totul este gata, să începem FreeCAD, să creăm un nou document și, în interpretorul python, să tastăm:

import exercise

Dacă nu apare niciun mesaj de eroare, înseamnă că scriptul nostru de exerciții exercise a fost încărcat. Acum îi putem verifica conținutul cu:

dir(exercise)

Comanda dir() este o comandă python încorporată care listează/enumeră conținutul unui modul. Putem vedea că clasa noastră class line() este aici, așteptându-ne. Acum, să o testăm:

'line' in dir(exercise)

Now let's test it:

exercise.line()

Apoi, faceți dublu clic în vizualizarea 3D, și bingo, aici este linia noastră! Pentru a face din nou, doar tastați exercise.line() din nou, și din nou și din nou ... Vă simțiți minunat, nu-i așa?

top

Înregistrarea scriptului în interfața FreeCAD

Acum, pentru ca noul nostru instrument de trasat linii să fie foarte cool, ar trebui să aibă un buton pe interfață, deci să nu trebuiescă să tastăm toate acele lucruri de fiecare dată. Cea mai ușoară cale este să ne transformăm noul director MyScripts într-un atelier de lucru complet FreeCAD. Este ușor, tot ce este necesar este să plasați un fișier numit InitGui.py în directorul MyScripts. InitGui.py va conține instrucțiunile pentru a crea un nou atelier de lucru și va adăuga noul instrument. În plus, va trebui să transformăm un pic codul nostru de exerciții, astfel încât instrumentul line() este recunoscut ca o comandă oficială FreeCAD. Să începem prin a face un fișier InitGui.py și scrieți următorul cod în el:

For our new line tool to be really useful, and to avoid having to type all that stuff, it should have a button in the interface. One way to do this is to transform our new MyScripts folder into a full FreeCAD workbench. This is easy, all that is needed is to put a file called InitGui.py inside the MyScripts folder. InitGui.py will contain the instructions to create a new workbench, and add our new tool to it. Besides that we will also need to change our exercise code a bit, so the line() tool is recognized as an official FreeCAD command. Let's start by creating an InitGui.py file, and writing the following code in it:

class MyWorkbench (Workbench):

    MenuText = "MyScripts"

    def Initialize(self):
        import exercise
        commandslist = ["line"]
        self.appendToolbar("My Scripts", commandslist)

Gui.addWorkbench(MyWorkbench())

Până acum, ar fi trebuit să fi înțeles deja scriptul de mai sus, mă gândesc eu: Creați o nouă clasă pe care o numiți MyWorkbench. Îi vom da un titlu (MenuText) și vom defini o funcție Initialize() care va fi executată atunci când atelierul de lucru este încărcat în FreeCAD. În această funcție, încărcăm conținutul fișierului de exerciții și adăugăm comenzile FreeCAD găsite în interiorul unei liste de comenzi. Apoi, facem o bară de instrumente numită "Scripturile mele" și îi atribuim comenzile noastre. În prezent, desigur, avem doar un singur instrument, astfel că lista noastră de comenzi conține doar un singur element. Apoi, odată ce atelierul nostru de lucru este gata, îl adăugăm la interfața principală.

Dar acest lucru nu va funcționa, deoarece o comandă FreeCAD trebuie să fie formatată într-un anumit mod de lucru. Deci, va trebui să transformăm puțin instrumentul nostru line(). Noul nostu script exercise.py va arăta cam așa:

import FreeCADGui, Part
from pivy.coin import *

class line:

    """This class will create a line after the user clicked 2 points on the screen"""

    def Activated(self):
        self.view = FreeCADGui.ActiveDocument.ActiveView
        self.stack = []
        self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(), self.getpoint)

    def getpoint(self, event_cb):
        event = event_cb.getEvent()
        if event.getState() == SoMouseButtonEvent.DOWN:
            pos = event.getPosition()
            point = self.view.getPoint(pos[0], pos[1])
            self.stack.append(point)
            if len(self.stack) == 2:
                l = Part.LineSegment(self.stack[0], self.stack[1])
                shape = l.toShape()
                Part.show(shape)
                self.view.removeEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(), self.callback)

    def GetResources(self):
        return {'Pixmap': 'path_to_an_icon/line_icon.png', 'MenuText': 'Line', 'ToolTip': 'Creates a line by clicking 2 points on the screen'}

FreeCADGui.addCommand('line', line())

Ceea ce am făcut aici? noi am transformat funcția noastră __init__() function într-o funcție Activated(), deoarece atunci când comenzile FreeCAD sunt executate, ele execută automat funcția Activated(). Am adăugat, de asemenea, o funcție GetResources (), care informează FreeCAD unde poate găsi o pictogramă pentru instrument și care va fi numele și sugestia/indicația instrumentului nostru. Orice imagine jpg, png sau svg va funcționa ca o pictogramă/iconiță, poate fi orice dimensiune, dar este mai bine să utilizați o dimensiune care este aproape de aspectul final, cum ar fi 16x16, 24x24 sau 32x32. Apoi, adăugăm class line() ca o comandă oficială FreeCAD cu metoda addCommand().

Asta este, vrem să reporniți FreeCAD și vom avea un nou atelier de lucru cu noul nostru instrument linie line!

top

Deci vrei mai mult?

Dacă ți-a plăcut acest exercițiu, de ce să nu încerci să îmbunătățești acest mic instrument? Sunt multe lucruri care pot fi făcute, ca de exemplu:

  • Adăugați comentarii utilizatorilor: până acum am făcut un instrument foarte subțire îmbrăcat, utilizatorul ar putea fi un pic pierdut atunci când îl utilizează. Așadar, am putea adăuga comentarii, spunându-i ce să facă în continuare. De exemplu, puteți emite mesaje către consola FreeCAD. ”Aruncați o privire” în modulul FreeCAD.Console
  • Adăugați posibilitatea de a introduce manual coordonatele punctelor 3D. Uitați-vă la funcția python input(), de exemplu,
  • Adăugați posibilitatea de a adăuga mai mult de 2 puncte
  • Adăugați evenimente pentru alte lucruri: Acum verificăm doar evenimentele butonului mouse-ului, dacă am face și ceva când mouse-ul este mutat, cum ar fi afișarea coordonatelor curente?
  • Dați un nume obiectului creat și multe alte lucruri.

Nu ezitați să vă scrieți întrebările sau ideile pe forum!

Don't hesitate to ask questions or share ideas on the forum!

top