0024665: A sample for advanced function mechanism
authorvro <vro@opencascade.com>
Wed, 10 Feb 2016 05:04:45 +0000 (08:04 +0300)
committerabv <abv@opencascade.com>
Sat, 20 Feb 2016 10:04:31 +0000 (13:04 +0300)
PRO file is added + a description of how to generate the Visual Studio projects and compile.
In addition, the sample folder is renamed to FuncDemo.

Adding 64 bit configuration to VC projects

41 files changed:
samples/qt/FuncDemo/FuncDemo-vc10.sln [new file with mode: 0644]
samples/qt/FuncDemo/FuncDemo-vc11.sln [new file with mode: 0644]
samples/qt/FuncDemo/FuncDemo-vc12.sln [new file with mode: 0644]
samples/qt/FuncDemo/FuncDemo.pro [new file with mode: 0644]
samples/qt/FuncDemo/ReadMe.md [new file with mode: 0644]
samples/qt/FuncDemo/custom.bat [new file with mode: 0644]
samples/qt/FuncDemo/env.bat [new file with mode: 0644]
samples/qt/FuncDemo/genproj.bat [new file with mode: 0644]
samples/qt/FuncDemo/images/new.png [new file with mode: 0644]
samples/qt/FuncDemo/images/open.png [new file with mode: 0644]
samples/qt/FuncDemo/images/save.png [new file with mode: 0644]
samples/qt/FuncDemo/make.sh [new file with mode: 0644]
samples/qt/FuncDemo/msvc.bat [new file with mode: 0644]
samples/qt/FuncDemo/run.bat [new file with mode: 0644]
samples/qt/FuncDemo/src/BaseDriver.cpp [new file with mode: 0644]
samples/qt/FuncDemo/src/BaseDriver.h [new file with mode: 0644]
samples/qt/FuncDemo/src/CircleDriver.cpp [new file with mode: 0644]
samples/qt/FuncDemo/src/CircleDriver.h [new file with mode: 0644]
samples/qt/FuncDemo/src/ConeDriver.cpp [new file with mode: 0644]
samples/qt/FuncDemo/src/ConeDriver.h [new file with mode: 0644]
samples/qt/FuncDemo/src/CylinderDriver.cpp [new file with mode: 0644]
samples/qt/FuncDemo/src/CylinderDriver.h [new file with mode: 0644]
samples/qt/FuncDemo/src/FThread.cpp [new file with mode: 0644]
samples/qt/FuncDemo/src/FThread.h [new file with mode: 0644]
samples/qt/FuncDemo/src/PointDriver.cpp [new file with mode: 0644]
samples/qt/FuncDemo/src/PointDriver.h [new file with mode: 0644]
samples/qt/FuncDemo/src/PrismDriver.cpp [new file with mode: 0644]
samples/qt/FuncDemo/src/PrismDriver.h [new file with mode: 0644]
samples/qt/FuncDemo/src/ShapeSaverDriver.cpp [new file with mode: 0644]
samples/qt/FuncDemo/src/ShapeSaverDriver.h [new file with mode: 0644]
samples/qt/FuncDemo/src/SimpleDriver.cpp [new file with mode: 0644]
samples/qt/FuncDemo/src/SimpleDriver.h [new file with mode: 0644]
samples/qt/FuncDemo/src/edge.cpp [new file with mode: 0644]
samples/qt/FuncDemo/src/edge.h [new file with mode: 0644]
samples/qt/FuncDemo/src/graphwidget.cpp [new file with mode: 0644]
samples/qt/FuncDemo/src/graphwidget.h [new file with mode: 0644]
samples/qt/FuncDemo/src/main.cpp [new file with mode: 0644]
samples/qt/FuncDemo/src/mainwindow.cpp [new file with mode: 0644]
samples/qt/FuncDemo/src/mainwindow.h [new file with mode: 0644]
samples/qt/FuncDemo/src/node.cpp [new file with mode: 0644]
samples/qt/FuncDemo/src/node.h [new file with mode: 0644]

diff --git a/samples/qt/FuncDemo/FuncDemo-vc10.sln b/samples/qt/FuncDemo/FuncDemo-vc10.sln
new file mode 100644 (file)
index 0000000..82a314f
--- /dev/null
@@ -0,0 +1,24 @@
+\feff
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FuncDemo-vc10", "FuncDemo-vc10.vcxproj", "{F2D59C5F-5C24-30CF-AD15-5EFBBA975C97}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Win32 = Debug|Win32
+               Debug|x64 = Debug|x64
+               Release|Win32 = Release|Win32
+               Release|x64 = Release|x64
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {F2D59C5F-5C24-30CF-AD15-5EFBBA975C97}.Debug|Win32.ActiveCfg = Debug|x64
+               {F2D59C5F-5C24-30CF-AD15-5EFBBA975C97}.Debug|x64.ActiveCfg = Release|x64
+               {F2D59C5F-5C24-30CF-AD15-5EFBBA975C97}.Debug|x64.Build.0 = Release|x64
+               {F2D59C5F-5C24-30CF-AD15-5EFBBA975C97}.Release|Win32.ActiveCfg = Release|x64
+               {F2D59C5F-5C24-30CF-AD15-5EFBBA975C97}.Release|x64.ActiveCfg = Release|x64
+               {F2D59C5F-5C24-30CF-AD15-5EFBBA975C97}.Release|x64.Build.0 = Release|x64
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+EndGlobal
diff --git a/samples/qt/FuncDemo/FuncDemo-vc11.sln b/samples/qt/FuncDemo/FuncDemo-vc11.sln
new file mode 100644 (file)
index 0000000..b9a14ef
--- /dev/null
@@ -0,0 +1,22 @@
+\feff
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FuncDemo-vc11", "FuncDemo-vc11.vcxproj", "{2D45A075-9BD9-385B-9361-B8E6DB02E623}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Win32 = Debug|Win32
+               Debug|x64 = Debug|x64
+               Release|Win32 = Release|Win32
+               Release|x64 = Release|x64
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {2D45A075-9BD9-385B-9361-B8E6DB02E623}.Debug|Win32.ActiveCfg = Debug|x64
+               {2D45A075-9BD9-385B-9361-B8E6DB02E623}.Debug|x64.ActiveCfg = Debug|x64
+               {2D45A075-9BD9-385B-9361-B8E6DB02E623}.Release|Win32.ActiveCfg = Release|x64
+               {2D45A075-9BD9-385B-9361-B8E6DB02E623}.Release|x64.ActiveCfg = Release|x64
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+EndGlobal
diff --git a/samples/qt/FuncDemo/FuncDemo-vc12.sln b/samples/qt/FuncDemo/FuncDemo-vc12.sln
new file mode 100644 (file)
index 0000000..a0d6439
--- /dev/null
@@ -0,0 +1,24 @@
+\feff
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.40629.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FuncDemo-vc12", "FuncDemo-vc12.vcxproj", "{10FEA026-33D8-3FA2-904F-8B99F5CC7A8F}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Win32 = Debug|Win32
+               Debug|x64 = Debug|x64
+               Release|Win32 = Release|Win32
+               Release|x64 = Release|x64
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {10FEA026-33D8-3FA2-904F-8B99F5CC7A8F}.Debug|Win32.ActiveCfg = Debug|x64
+               {10FEA026-33D8-3FA2-904F-8B99F5CC7A8F}.Debug|x64.ActiveCfg = Debug|x64
+               {10FEA026-33D8-3FA2-904F-8B99F5CC7A8F}.Release|Win32.ActiveCfg = Release|x64
+               {10FEA026-33D8-3FA2-904F-8B99F5CC7A8F}.Release|x64.ActiveCfg = Release|x64
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+EndGlobal
diff --git a/samples/qt/FuncDemo/FuncDemo.pro b/samples/qt/FuncDemo/FuncDemo.pro
new file mode 100644 (file)
index 0000000..c6bb1dc
--- /dev/null
@@ -0,0 +1,91 @@
+######################################################################
+# Automatically generated by qmake (2.01a) ?? 11. ??? 12:03:38 2016
+######################################################################
+
+TEMPLATE = app
+TARGET = 
+DEPENDPATH += . src
+INCLUDEPATH += .
+
+# Input
+HEADERS += src/BaseDriver.h \
+           src/CircleDriver.h \
+           src/ConeDriver.h \
+           src/CylinderDriver.h \
+           src/edge.h \
+           src/FThread.h \
+           src/graphwidget.h \
+           src/mainwindow.h \
+           src/node.h \
+           src/PointDriver.h \
+           src/PrismDriver.h \
+           src/ShapeSaverDriver.h \
+           src/SimpleDriver.h
+SOURCES += src/BaseDriver.cpp \
+           src/CircleDriver.cpp \
+           src/ConeDriver.cpp \
+           src/CylinderDriver.cpp \
+           src/edge.cpp \
+           src/FThread.cpp \
+           src/graphwidget.cpp \
+           src/main.cpp \
+           src/mainwindow.cpp \
+           src/node.cpp \
+           src/PointDriver.cpp \
+           src/PrismDriver.cpp \
+           src/ShapeSaverDriver.cpp \
+           src/SimpleDriver.cpp
+
+INCLUDEPATH += $$quote($$(CASROOT)/inc)
+
+OCCT_DEFINES = $$(CSF_DEFINES)
+
+DEFINES = $$split(OCCT_DEFINES, ;)
+
+unix {
+    UNAME = $$system(uname -s)
+    LIBLIST = $$(LD_LIBRARY_PATH)
+    LIBPATHS = $$split(LIBLIST,":")
+    for(lib, LIBPATHS):LIBS += -L$${lib}
+
+    CONFIG(debug, debug|release) {
+        DESTDIR = ./$$UNAME/bind
+        OBJECTS_DIR = ./$$UNAME/objd
+        MOC_DIR = ./src
+    } else {
+        DESTDIR = ./$$UNAME/bin
+        OBJECTS_DIR = ./$$UNAME/obj
+        MOC_DIR = ./src
+    }
+
+    MACOSX_USE_GLX = $$(MACOSX_USE_GLX)
+
+    !macx | equals(MACOSX_USE_GLX, true): INCLUDEPATH += $$QMAKE_INCDIR_X11 $$QMAKE_INCDIR_OPENGL $$QMAKE_INCDIR_THREAD
+    equals(MACOSX_USE_GLX, true): DEFINES += MACOSX_USE_GLX
+    DEFINES += OCC_CONVERT_SIGNALS QT_NO_STL
+    !macx | equals(MACOSX_USE_GLX, true): LIBS += -L$$QMAKE_LIBDIR_X11 $$QMAKE_LIBS_X11 -L$$QMAKE_LIBDIR_OPENGL $$QMAKE_LIBS_OPENGL $$QMAKE_LIBS_THREAD
+    QMAKE_CXXFLAGS += -std=gnu++11
+}
+
+win32 {
+    CONFIG(debug, debug|release) {
+        DEFINES += _DEBUG
+        DESTDIR = ./win$(ARCH)/$(VCVER)/bind
+        OBJECTS_DIR = ./win$(ARCH)/$(VCVER)/objd
+        MOC_DIR = ./src
+        LIBS = -L$$(QTDIR)/lib;$$(CASROOT)/win$$(ARCH)/$$(VCVER)/libd
+    } else {
+        DEFINES += NDEBUG
+        DESTDIR = ./win$(ARCH)/$(VCVER)/bin
+        OBJECTS_DIR = ./win$(ARCH)/$(VCVER)/obj
+        MOC_DIR = ./src
+        LIBS = -L$$(QTDIR)/lib;$$(CASROOT)/win$$(ARCH)/$$(VCVER)/lib
+    }
+}
+
+LIBS += -lTKernel -lTKMath -lTKBRep -lTKGeomBase -lTKGeomAlgo -lTKG3d -lTKG2d \
+        -lTKTopAlgo -lTKMesh -lTKPrim -lTKCDF -lTKLCAF -lTKCAF -lTKBO
+
+greaterThan(QT_MAJOR_VERSION, 4) {
+    QT += widgets
+}
diff --git a/samples/qt/FuncDemo/ReadMe.md b/samples/qt/FuncDemo/ReadMe.md
new file mode 100644 (file)
index 0000000..9090437
--- /dev/null
@@ -0,0 +1,30 @@
+Advanced Function Mechanism sample application
+============================================== 
+
+This sample demonstrates a simple way of using an advanced function mechanism of Ocaf.
+
+Description
+=========== 
+The sample application represents a window demontsrating calculation of two simple models by the advanced function mechanism. The models are displayed as a graph (colored circles connected to each other). The links between circles define the dependences of the sample functions. Having pressed the button "Compute" the user may see how the function mechanism calculates the functions - the calculated circles change the color to yellow (indicating the process of calculation) and then, to blue - the function is computed. It is possible to define the number of threads to be used by the function mechanism (up to 4, just a limitation of this sample application). Having chosen 4 threads, for example, the user may see how the functions are calculated by 4 at once.
+
+Compilation
+===========
+Run genproj.bat in a command-line to generate Visual Studio projects. For example, for Visual Studio 2010 call this line:
+>genproj vc10 win32 debug
+It generates VCPROJ (or VCXPROJ) files. Then, call the Visual Studio:
+msvc vc10 win32 debug
+
+Usage
+=====
+There are 4 menu-items:
+Model \ Model1 - chooses the 1st test model. The application clears the previously selected model and displays a set of connected green circles (functions). You may move the circles by mouse for more convenient view.
+Model \ Model2 - chooses the 2nd test model. It behaves the same as the Model1 described above.
+Model \ Compute - runs the calculation of the chosen model in multi-threaded mode.
+Model \ Number of threads - defines the number of threads (up to 4, for this sample application) to be used for calculation of a chosen model.
+
+Implementation
+==============
+The models (Model1 and Model2) are hard-coded in MainWindow.cpp in the methods createDefaultModel1() and createDefaultModel2().
+The Model1 represents a set of dependent "simple" functions. By "simple" I mean the function without a meaning. In other words, it doesn't matter what the function do, it is important how it depends on other functions and how it is being calculated by the function mechanism.
+The Model2 has more meaning. It represents a process of creation of a shape. A Circle depends on a Point, A Prism is built on a Circle, ...
+
diff --git a/samples/qt/FuncDemo/custom.bat b/samples/qt/FuncDemo/custom.bat
new file mode 100644 (file)
index 0000000..895b72e
--- /dev/null
@@ -0,0 +1,3 @@
+@echo off
+rem Define QTDIR variable
+set QTDIR=D:\Qt\4.8.2
diff --git a/samples/qt/FuncDemo/env.bat b/samples/qt/FuncDemo/env.bat
new file mode 100644 (file)
index 0000000..e00ecf8
--- /dev/null
@@ -0,0 +1,8 @@
+@echo off
+
+call "custom.bat" %1 %2 %3
+
+call "%~dp0..\..\..\env.bat" %1 %2 %3
+
+set "PATH=%QTDIR%/bin;%PATH%"
+set "QT_QPA_PLATFORM_PLUGIN_PATH=%QTDIR%\plugins\platforms"
\ No newline at end of file
diff --git a/samples/qt/FuncDemo/genproj.bat b/samples/qt/FuncDemo/genproj.bat
new file mode 100644 (file)
index 0000000..0ab4ea9
--- /dev/null
@@ -0,0 +1,44 @@
+@echo off
+REM Generation of vcproj files with qmake utilite
+REM Variable QTDIR and PATH to qmake executable must be defined without fail
+
+REM Use first argument to specify version of Visual Studio (vc8, vc9, or vc10),
+REM second argument specifies architecture) (win32 or win64)
+REM third argument specifies Debug or Release mode
+
+call "%~dp0env.bat" %1 %2 %3
+
+set EXT=vcproj
+
+if not "%VCVER%" == "" (
+    if /I "%VCVER%" == "vc8" (
+        set VCVER=vc8
+        set "VCVARS=%VS80COMNTOOLS%..\..\VC\vcvarsall.bat"
+    ) else if /I "%VCVER%" == "vc9" (
+        set VCVER=vc9
+        set "VCVARS=%VS90COMNTOOLS%..\..\VC\vcvarsall.bat"
+    ) else if /I "%VCVER%" == "vc10" (
+        set VCVER=vc10
+       set EXT=vcxproj
+        set "VCVARS=%VS100COMNTOOLS%..\..\VC\vcvarsall.bat"
+    ) else if /I "%VCVER%" == "vc11" (
+        set VCVER=vc11
+       set EXT=vcxproj
+        set "VCVARS=%VS110COMNTOOLS%..\..\VC\vcvarsall.bat"
+    ) else if /I "%VCVER%" == "vc12" (
+        set VCVER=vc12
+       set EXT=vcxproj
+        set "VCVARS=%VS120COMNTOOLS%..\..\VC\vcvarsall.bat"
+    ) else (
+        echo Error: first argument ^(%VCVER%^) should specify supported version of Visual C++,
+        echo one of: vc8 ^(VS 2005 SP1^), vc9 ^(VS 2008 SP1^), vc10 ^(VS 2010^) or vc11 ^(VS 2012^)
+        exit
+    )
+)
+
+if ["%ARCH%"] == ["32"] set VCARCH=x86
+if ["%ARCH%"] == ["64"] set VCARCH=amd64
+
+call "%VCVARS%" %VCARCH%
+
+qmake -tp vc -o FuncDemo-%VCVER%.%EXT% FuncDemo.pro
diff --git a/samples/qt/FuncDemo/images/new.png b/samples/qt/FuncDemo/images/new.png
new file mode 100644 (file)
index 0000000..12131b0
Binary files /dev/null and b/samples/qt/FuncDemo/images/new.png differ
diff --git a/samples/qt/FuncDemo/images/open.png b/samples/qt/FuncDemo/images/open.png
new file mode 100644 (file)
index 0000000..45fa288
Binary files /dev/null and b/samples/qt/FuncDemo/images/open.png differ
diff --git a/samples/qt/FuncDemo/images/save.png b/samples/qt/FuncDemo/images/save.png
new file mode 100644 (file)
index 0000000..daba865
Binary files /dev/null and b/samples/qt/FuncDemo/images/save.png differ
diff --git a/samples/qt/FuncDemo/make.sh b/samples/qt/FuncDemo/make.sh
new file mode 100644 (file)
index 0000000..8fc47f6
--- /dev/null
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+export aSamplePath="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+if [ -e "${aSamplePath}/env.sh" ]; then source "${aSamplePath}/env.sh"; fi
+cd $aSamplePath
+qmake FuncDemo.pro
+if [ "$(uname -s)" != "Darwin" ] || [ "$MACOSX_USE_GLX" == "true" ]; then
+  if [ "${CASDEB}" == "d" ]; then
+    make debug
+  else
+    make release
+  fi
+fi
diff --git a/samples/qt/FuncDemo/msvc.bat b/samples/qt/FuncDemo/msvc.bat
new file mode 100644 (file)
index 0000000..25c88cb
--- /dev/null
@@ -0,0 +1,38 @@
+@echo off
+
+rem Setup environment
+call "%~dp0env.bat" %1 %2 %3
+
+rem Define path to project file
+set "PRJFILE=%~dp0FuncDemo-%VCVER%.sln"
+
+set "VisualStudioExpressName=VCExpress"
+
+if "%VCVER%" == "vc8" (
+  set "DevEnvDir=%VS80COMNTOOLS%..\IDE"
+) else if "%VCVER%" == "vc9" (
+  set "DevEnvDir=%VS90COMNTOOLS%..\IDE"
+) else if "%VCVER%" == "vc10" (
+  set "DevEnvDir=%VS100COMNTOOLS%..\IDE"
+) else if "%VCVER%" == "vc11" (
+  set "DevEnvDir=%VS110COMNTOOLS%..\IDE"
+  rem Visual Studio Express starting from VS 2012 is called "for Windows Desktop"
+  rem and has a new name for executable - WDExpress
+  set "VisualStudioExpressName=WDExpress"
+) else if "%VCVER%" == "vc12" (
+  set "DevEnvDir=%VS120COMNTOOLS%..\IDE"
+  set "VisualStudioExpressName=WDExpress"
+) else (
+  echo Error: wrong VS identifier
+  exit /B
+)
+
+rem Launch Visual Studio - either professional (devenv) or Express, as available
+if exist "%DevEnvDir%\devenv.exe"  (
+  start "%DevEnvDir%\devenv.exe" "%PRJFILE%"
+) else if exist "%DevEnvDir%\%VisualStudioExpressName%.exe"  (
+  start "%DevEnvDir%\%VisualStudioExpressName%.exe" "%PRJFILE%"
+) else (
+  echo Error: Could not find MS Visual Studio ^(%VCVER%^)
+  echo Check relevant environment variable ^(e.g. VS80COMNTOOLS for vc8^)
+)
diff --git a/samples/qt/FuncDemo/run.bat b/samples/qt/FuncDemo/run.bat
new file mode 100644 (file)
index 0000000..fc0c498
--- /dev/null
@@ -0,0 +1,21 @@
+call "%~dp0env.bat" %1 %2 %3
+
+set "BIN_DIR=win%ARCH%\%VCVER%\bind"
+if ["%CASDEB%"] == [""] (
+  set "BIN_DIR=win%ARCH%\%VCVER%\bin"
+)
+
+if not exist "%~dp0%BIN_DIR%\FuncDemo.exe" goto ERR_EXE
+
+echo Starting Demo .....
+"%~dp0%BIN_DIR%\FuncDemo.exe"
+
+goto END
+
+:ERR_EXE
+echo Executable %~dp0%BIN_DIR%\FuncDemo.exe not found.
+echo Probably you didn't compile the application.
+pause
+goto END
+
+:END
\ No newline at end of file
diff --git a/samples/qt/FuncDemo/src/BaseDriver.cpp b/samples/qt/FuncDemo/src/BaseDriver.cpp
new file mode 100644 (file)
index 0000000..37ee158
--- /dev/null
@@ -0,0 +1,66 @@
+// BaseDriver.cpp: implementation of the BaseDriver class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "BaseDriver.h"
+
+#include <TDF_Reference.hxx>
+#include <TDF_ChildIterator.hxx>
+
+#define SLOW
+#ifdef SLOW
+#include <OSD_Timer.hxx>
+#include <BRepPrimAPI_MakeSphere.hxx>
+#include <BRepAlgoAPI_Fuse.hxx>
+#endif
+
+IMPLEMENT_STANDARD_HANDLE(BaseDriver,TFunction_Driver)
+IMPLEMENT_STANDARD_RTTIEXT(BaseDriver,TFunction_Driver)
+
+// Constructor
+BaseDriver::BaseDriver()
+{
+
+}
+
+// Returns the arguments of the function
+void BaseDriver::Arguments(TDF_LabelList& args) const
+{
+    // Append all arguments.
+    TDF_ChildIterator itr(Label().FindChild(1), false);
+    for (; itr.More(); itr.Next())
+    {
+        Handle(TDF_Reference) ref;
+        if (itr.Value().FindAttribute(TDF_Reference::GetID(), ref))
+            args.Append(ref->Get());
+    }
+}
+
+
+// Returns the results of the function
+void BaseDriver::Results(TDF_LabelList& res) const
+{
+    // Append all results
+    TDF_ChildIterator itr(Label().FindChild(2), false);
+    for (; itr.More(); itr.Next())
+    {
+        Handle(TDF_Reference) ref;
+        if (itr.Value().FindAttribute(TDF_Reference::GetID(), ref))
+            res.Append(ref->Get());
+    }
+}
+
+// Execution.
+Standard_Integer BaseDriver::Execute(Handle(TFunction_Logbook)& log) const
+{
+#ifdef SLOW
+    // Make a boolean operation to slow down the function
+    TopoDS_Shape S1 = BRepPrimAPI_MakeSphere(100.0, 2.0 * M_PI / 3.0);
+    TopoDS_Shape S2 = BRepPrimAPI_MakeSphere(gp_Pnt(10, 10, 10), 100.0, 2.0 * M_PI / 3.0);
+    BRepAlgoAPI_Fuse fuser(S1, S2);
+    fuser.Build();
+#endif
+
+    // Empty... should be implemented in descendent classes
+    return 0;
+}
\ No newline at end of file
diff --git a/samples/qt/FuncDemo/src/BaseDriver.h b/samples/qt/FuncDemo/src/BaseDriver.h
new file mode 100644 (file)
index 0000000..ab23adb
--- /dev/null
@@ -0,0 +1,39 @@
+// BaseDriver.h: interface for the Base function driver.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(_BASEDRIVER_H_)
+#define _BASEDRIVER_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include <Standard_DefineHandle.hxx> 
+#include <TFunction_Driver.hxx>
+#include <TFunction_Logbook.hxx>
+#include <TDF_LabelList.hxx>
+
+DEFINE_STANDARD_HANDLE(BaseDriver, TFunction_Driver)
+
+// A base function driver.
+class BaseDriver : public TFunction_Driver
+{
+public:
+    
+    // Constructor
+       BaseDriver();
+
+       // Returns the arguments of the function
+       virtual void Arguments(TDF_LabelList& args) const;
+
+       // Returns the results of the function
+       virtual void Results(TDF_LabelList& res) const;
+
+       // Execution.
+       virtual Standard_Integer Execute(Handle(TFunction_Logbook)& log) const;
+
+       DEFINE_STANDARD_RTTIEXT(BaseDriver, TFunction_Driver)
+};
+
+#endif // !defined(_BASEDRIVER_H_)
diff --git a/samples/qt/FuncDemo/src/CircleDriver.cpp b/samples/qt/FuncDemo/src/CircleDriver.cpp
new file mode 100644 (file)
index 0000000..3fbf732
--- /dev/null
@@ -0,0 +1,76 @@
+// CircleDriver.cpp: implementation of the CircleDriver class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "CircleDriver.h"
+
+#include <Standard_GUID.hxx>
+#include <TDF_Reference.hxx>
+#include <TNaming_Builder.hxx>
+#include <TNaming_NamedShape.hxx>
+#include <TDataStd_Real.hxx>
+
+#include <TopoDS.hxx>
+#include <gp_Circ.hxx>
+#include <BRep_Tool.hxx>
+#include <Precision.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Wire.hxx>
+#include <TopoDS_Face.hxx>
+#include <BRepBuilderAPI_MakeEdge.hxx>
+#include <BRepBuilderAPI_MakeWire.hxx>
+#include <BRepBuilderAPI_MakeFace.hxx>
+
+IMPLEMENT_STANDARD_HANDLE(CircleDriver,BaseDriver)
+IMPLEMENT_STANDARD_RTTIEXT(CircleDriver,BaseDriver)
+
+// ID of the function driver
+const Standard_GUID& CircleDriver::GetID()
+{
+    static const Standard_GUID id("D10515D5-7C4E-4fe3-A7E2-DE2E01859B4D");
+    return id;
+}
+
+// Constructor
+CircleDriver::CircleDriver()
+{
+
+}
+
+// Execution.
+Standard_Integer CircleDriver::Execute(Handle(TFunction_Logbook)& log) const
+{
+    // Usual check...
+    if (Label().IsNull())
+        return 1;
+
+    // Take the arguments (radius)
+    Handle(TDataStd_Real) r;
+    if (!Label().FindAttribute(TDataStd_Real::GetID(), r))
+        return 2;
+    double radius = r->Get();
+    if (radius < Precision::Confusion())
+        return 3;
+
+    // Take the arguments (center point)
+    Handle(TDF_Reference) ref;
+    TDF_Label Lpoint = Label().FindChild(1).FindChild(1);
+    if (!Lpoint.FindAttribute(TDF_Reference::GetID(), ref))
+        return 4;
+    Handle(TNaming_NamedShape) n;
+    if (!ref->Get().FindAttribute(TNaming_NamedShape::GetID(), n) || n->IsEmpty())
+        return 5;
+    TopoDS_Vertex V = TopoDS::Vertex(n->Get());
+
+    // Make the result
+    gp_Circ C(gp_Ax2(BRep_Tool::Pnt(V), gp::DZ()), radius);
+    TopoDS_Edge E = BRepBuilderAPI_MakeEdge(C);
+    TopoDS_Wire W = BRepBuilderAPI_MakeWire(E);
+    TopoDS_Face F = BRepBuilderAPI_MakeFace(W);
+
+    // Set the result
+    TNaming_Builder B(Label());
+    B.Generated(F);
+
+    return BaseDriver::Execute(log);
+}
\ No newline at end of file
diff --git a/samples/qt/FuncDemo/src/CircleDriver.h b/samples/qt/FuncDemo/src/CircleDriver.h
new file mode 100644 (file)
index 0000000..3e3be8b
--- /dev/null
@@ -0,0 +1,36 @@
+// CircleDriver.h: interface for the Circle function driver.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(_CIRCLEDRIVER_H_)
+#define _CIRCLEDRIVER_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "BaseDriver.h"
+
+#include <Standard_DefineHandle.hxx> 
+#include <TFunction_Logbook.hxx>
+
+DEFINE_STANDARD_HANDLE(CircleDriver, BaseDriver)
+
+// A Circle function driver.
+class CircleDriver : public BaseDriver
+{
+public:
+
+    // ID of the function driver
+    static const Standard_GUID& GetID();
+    
+    // Constructor
+       CircleDriver();
+
+       // Execution.
+       virtual Standard_Integer Execute(Handle(TFunction_Logbook)& log) const;
+
+       DEFINE_STANDARD_RTTIEXT(CircleDriver, TFunction_Driver)
+};
+
+#endif // !defined(_CIRCLEDRIVER_H_)
diff --git a/samples/qt/FuncDemo/src/ConeDriver.cpp b/samples/qt/FuncDemo/src/ConeDriver.cpp
new file mode 100644 (file)
index 0000000..c1fe28b
--- /dev/null
@@ -0,0 +1,153 @@
+// ConeDriver.cpp: implementation of the ConeDriver class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "ConeDriver.h"
+
+#include <Standard_GUID.hxx>
+#include <TDF_Reference.hxx>
+#include <TNaming_Builder.hxx>
+#include <TNaming_NamedShape.hxx>
+#include <TDataStd_Real.hxx>
+
+#include <gp_Pnt.hxx>
+#include <gp_Circ.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Face.hxx>
+#include <Precision.hxx>
+#include <BRepAdaptor_Curve.hxx>
+#include <TopExp_Explorer.hxx>
+#include <BRepPrimAPI_MakeCone.hxx>
+#include <BRepBuilderAPI_MakeEdge.hxx>
+#include <BRepBuilderAPI_MakeWire.hxx>
+#include <BRepBuilderAPI_MakeFace.hxx>
+
+IMPLEMENT_STANDARD_HANDLE(ConeDriver,BaseDriver)
+IMPLEMENT_STANDARD_RTTIEXT(ConeDriver,BaseDriver)
+
+// ID of the function driver
+const Standard_GUID& ConeDriver::GetID()
+{
+    static const Standard_GUID id("73C5C048-59EC-404a-850B-08363D75E63C");
+    return id;
+}
+
+// Constructor
+ConeDriver::ConeDriver()
+{
+
+}
+
+// Execution.
+Standard_Integer ConeDriver::Execute(Handle(TFunction_Logbook)& log) const
+{
+    // Usual check...
+    if (Label().IsNull())
+        return 1;
+
+    // Take the arguments (height)
+    Handle(TDataStd_Real) h;
+    if (!Label().FindAttribute(TDataStd_Real::GetID(), h))
+        return 2;
+    double height = h->Get();
+    if (height < Precision::Confusion())
+        return 3;
+
+    // Take the arguments (top faces)
+    Handle(TDF_Reference) ref1, ref2, ref3, ref4;
+    if (!Label().FindChild(1).FindChild(1).FindAttribute(TDF_Reference::GetID(), ref1))
+        return 4;
+    if (!Label().FindChild(1).FindChild(2).FindAttribute(TDF_Reference::GetID(), ref2))
+        return 5;
+    if (!Label().FindChild(1).FindChild(3).FindAttribute(TDF_Reference::GetID(), ref3))
+        return 6;
+    if (!Label().FindChild(1).FindChild(4).FindAttribute(TDF_Reference::GetID(), ref4))
+        return 7;
+    Handle(TNaming_NamedShape) n1, n2, n3, n4;
+    if (!ref1->Get().FindAttribute(TNaming_NamedShape::GetID(), n1) || n1->IsEmpty())
+        return 8;
+    if (!ref2->Get().FindAttribute(TNaming_NamedShape::GetID(), n2) || n2->IsEmpty())
+        return 9;
+    if (!ref3->Get().FindAttribute(TNaming_NamedShape::GetID(), n3) || n3->IsEmpty())
+        return 10;
+    if (!ref4->Get().FindAttribute(TNaming_NamedShape::GetID(), n4) || n4->IsEmpty())
+        return 11;
+    TopoDS_Face F1 = TopoDS::Face(n1->Get());
+    TopoDS_Face F2 = TopoDS::Face(n2->Get());
+    TopoDS_Face F3 = TopoDS::Face(n3->Get());
+    TopoDS_Face F4 = TopoDS::Face(n4->Get());
+
+    // Compute central points
+    gp_Pnt p1, p2, p3, p4;
+    TopoDS_Edge E1, E2, E3, E4;
+    TopExp_Explorer expl(F1, TopAbs_EDGE);
+    if (!expl.More())
+        return 12;
+    E1 = TopoDS::Edge(expl.Current());
+    expl.Init(F2, TopAbs_EDGE);
+    if (!expl.More())
+        return 13;
+    E2 = TopoDS::Edge(expl.Current());
+    expl.Init(F3, TopAbs_EDGE);
+    if (!expl.More())
+        return 14;
+    E3 = TopoDS::Edge(expl.Current());
+    expl.Init(F4, TopAbs_EDGE);
+    if (!expl.More())
+        return 15;
+    E4 = TopoDS::Edge(expl.Current());
+    BRepAdaptor_Curve A(E1);
+    gp_Circ C1 = A.Circle();
+    p1 = C1.Location();
+    A.Initialize(E2);
+    gp_Circ C2 = A.Circle();
+    p2 = C2.Location();
+    A.Initialize(E3);
+    gp_Circ C3 = A.Circle();
+    p3 = C3.Location();
+    A.Initialize(E4);
+    gp_Circ C4 = A.Circle();
+    p4 = C4.Location();
+
+    // Center of cone
+    gp_Pnt p(0.25*(p1.X()+p2.X()+p3.X()+p4.X()),
+             0.25*(p1.Y()+p2.Y()+p3.Y()+p4.Y()),
+             0.25*(p1.Z()+p2.Z()+p3.Z()+p4.Z()));
+
+    // Bottom radius (max distance to points from center)
+    double bRadius = 0.0;
+    if (p1.Distance(p) > bRadius)
+        bRadius = p1.Distance(p);
+    if (p2.Distance(p) > bRadius)
+        bRadius = p2.Distance(p);
+    if (p3.Distance(p) > bRadius)
+        bRadius = p3.Distance(p);
+    if (p4.Distance(p) > bRadius)
+        bRadius = p4.Distance(p);
+    bRadius *= 1.5;
+
+    // Top radius
+    double tRadius = bRadius / 2.0;
+
+    // Make the result
+    BRepPrimAPI_MakeCone mkCone(gp_Ax2(p, gp::DZ()), bRadius, tRadius, height);
+    mkCone.Build();
+    if (!mkCone.IsDone())
+        return 16;
+    TopoDS_Shape C = mkCone.Shape();
+
+    // Make another result: a circle for next functions (many cylinders)
+    p.Translate(height * gp::DZ());
+    gp_Circ TC(gp_Ax2(p, gp::DZ()), 0.8 * tRadius);
+    TopoDS_Edge E = BRepBuilderAPI_MakeEdge(TC);
+    TopoDS_Wire W = BRepBuilderAPI_MakeWire(E);
+    TopoDS_Face F = BRepBuilderAPI_MakeFace(W);
+
+    // Set the result
+    TNaming_Builder B(Label());
+    B.Generated(C);
+    TNaming_Builder B2(Label().FindChild(3));
+    B2.Generated(F);
+
+    return BaseDriver::Execute(log);
+}
\ No newline at end of file
diff --git a/samples/qt/FuncDemo/src/ConeDriver.h b/samples/qt/FuncDemo/src/ConeDriver.h
new file mode 100644 (file)
index 0000000..c397b77
--- /dev/null
@@ -0,0 +1,36 @@
+// ConeDriver.h: interface for the Cone function driver.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(_CONEDRIVER_H_)
+#define _CONEDRIVER_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "BaseDriver.h"
+
+#include <Standard_DefineHandle.hxx> 
+#include <TFunction_Logbook.hxx>
+
+DEFINE_STANDARD_HANDLE(ConeDriver, BaseDriver)
+
+// A Cone function driver.
+class ConeDriver : public BaseDriver
+{
+public:
+
+    // ID of the function driver
+    static const Standard_GUID& GetID();
+    
+    // Constructor
+       ConeDriver();
+
+       // Execution.
+       virtual Standard_Integer Execute(Handle(TFunction_Logbook)& log) const;
+
+       DEFINE_STANDARD_RTTIEXT(ConeDriver, TFunction_Driver)
+};
+
+#endif // !defined(_CONEDRIVER_H_)
diff --git a/samples/qt/FuncDemo/src/CylinderDriver.cpp b/samples/qt/FuncDemo/src/CylinderDriver.cpp
new file mode 100644 (file)
index 0000000..fa9d5d3
--- /dev/null
@@ -0,0 +1,102 @@
+// CylinderDriver.cpp: implementation of the CylinderDriver class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "CylinderDriver.h"
+
+#include <Standard_GUID.hxx>
+#include <TDF_Reference.hxx>
+#include <TNaming_Builder.hxx>
+#include <TNaming_NamedShape.hxx>
+#include <TDataStd_RealArray.hxx>
+
+#include <TopoDS.hxx>
+#include <ElCLib.hxx>
+#include <gp_Circ.hxx>
+#include <Precision.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopExp_Explorer.hxx>
+#include <BRepAdaptor_Curve.hxx>
+#include <BRepBuilderAPI_MakeEdge.hxx>
+#include <BRepBuilderAPI_MakeWire.hxx>
+#include <BRepBuilderAPI_MakeFace.hxx>
+#include <BRepPrimAPI_MakeCylinder.hxx>
+
+IMPLEMENT_STANDARD_HANDLE(CylinderDriver,BaseDriver)
+IMPLEMENT_STANDARD_RTTIEXT(CylinderDriver,BaseDriver)
+
+// ID of the function driver
+const Standard_GUID& CylinderDriver::GetID()
+{
+    static const Standard_GUID id("9CE1FCDA-C8EA-4b09-B1C4-021FCD44F3F3");
+    return id;
+}
+
+// Constructor
+CylinderDriver::CylinderDriver()
+{
+
+}
+
+// Execution.
+Standard_Integer CylinderDriver::Execute(Handle(TFunction_Logbook)& log) const
+{
+    // Usual check...
+    if (Label().IsNull())
+        return 1;
+
+    // Take the arguments (radius, angle, height)
+    Handle(TDataStd_RealArray) arr;
+    if (!Label().FindAttribute(TDataStd_RealArray::GetID(), arr))
+        return 2;
+    double radius = arr->Value(1);
+    double angle = arr->Value(2);
+    double height = arr->Value(3);
+    if (radius < Precision::Confusion() || height < Precision::Confusion())
+        return 3;
+
+    // Take the arguments (top face)
+    Handle(TDF_Reference) ref;
+    if (!Label().FindChild(1).FindChild(1).FindAttribute(TDF_Reference::GetID(), ref))
+        return 4;
+    Handle(TNaming_NamedShape) n;
+    if (!ref->Get().FindAttribute(TNaming_NamedShape::GetID(), n) || n->IsEmpty())
+        return 5;
+    TopoDS_Face F = TopoDS::Face(n->Get());
+
+    // Take the circle
+    TopExp_Explorer expl(F, TopAbs_EDGE);
+    if (!expl.More())
+        return 6;
+    TopoDS_Edge E = TopoDS::Edge(expl.Current());
+    BRepAdaptor_Curve A(E);
+    gp_Circ C = A.Circle();
+
+    // Center of the cylinder
+    gp_Pnt p = ElCLib::Value(angle * M_PI / 180.0, C);
+    gp_Vec v(p, C.Location());
+    v.Normalize();
+    p.Translate(radius * v);
+
+    // Make the result
+    BRepPrimAPI_MakeCylinder mkCylinder(gp_Ax2(p, gp::DZ()), radius, height);
+    mkCylinder.Build();
+    if (!mkCylinder.IsDone())
+        return 7;
+    TopoDS_Shape Cyl = mkCylinder.Shape();
+
+    // Make the top face of the cylinder for next functions
+    gp_Circ Ctop(gp_Ax2(p.Translated(height * gp::DZ()), gp::DZ()), radius);
+    TopoDS_Edge Etop = BRepBuilderAPI_MakeEdge(Ctop);
+    TopoDS_Wire Wtop = BRepBuilderAPI_MakeWire(Etop);
+    TopoDS_Face Ftop = BRepBuilderAPI_MakeFace(Wtop);
+
+    // Set the result
+    TNaming_Builder B(Label());
+    B.Generated(Cyl);
+    TNaming_Builder B2(Label().FindChild(3));
+    B2.Generated(Ftop);
+
+    return BaseDriver::Execute(log);
+}
\ No newline at end of file
diff --git a/samples/qt/FuncDemo/src/CylinderDriver.h b/samples/qt/FuncDemo/src/CylinderDriver.h
new file mode 100644 (file)
index 0000000..322d186
--- /dev/null
@@ -0,0 +1,36 @@
+// CylinderDriver.h: interface for the Cylinder function driver.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(_CYLINDERDRIVER_H_)
+#define _CYLINDERDRIVER_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "BaseDriver.h"
+
+#include <Standard_DefineHandle.hxx> 
+#include <TFunction_Logbook.hxx>
+
+DEFINE_STANDARD_HANDLE(CylinderDriver, BaseDriver)
+
+// A Cylinder function driver.
+class CylinderDriver : public BaseDriver
+{
+public:
+
+    // ID of the function driver
+    static const Standard_GUID& GetID();
+    
+    // Constructor
+       CylinderDriver();
+
+       // Execution.
+       virtual Standard_Integer Execute(Handle(TFunction_Logbook)& log) const;
+
+       DEFINE_STANDARD_RTTIEXT(CylinderDriver, TFunction_Driver)
+};
+
+#endif // !defined(_CYLINDERDRIVER_H_)
diff --git a/samples/qt/FuncDemo/src/FThread.cpp b/samples/qt/FuncDemo/src/FThread.cpp
new file mode 100644 (file)
index 0000000..06bbc0f
--- /dev/null
@@ -0,0 +1,126 @@
+#include "FThread.h"
+#include "GraphWidget.h"
+
+#include <TFunction_Function.hxx>
+#include <TFunction_IFunction.hxx>
+#include <TFunction_Driver.hxx>
+#include <TFunction_GraphNode.hxx>
+
+#include <TDataStd_Tick.hxx>
+#include <TDF_ListIteratorOfLabelList.hxx>
+
+FThread::FThread(QObject* parent):QThread(parent),thread_index(0)
+{
+
+}
+
+FThread::~FThread()
+{
+
+}
+
+void FThread::setIterator(const TFunction_Iterator& itr)
+{
+    this->itr = itr;
+}
+
+void FThread::setLogbook(const Handle(TFunction_Logbook)& log)
+{
+    this->log = log;
+}
+
+void FThread::setGraph(GraphWidget* graph)
+{
+    this->graph = graph;
+}
+
+void FThread::setThreadIndex(const int thread_index)
+{
+    this->thread_index = thread_index;
+}
+
+// Returns any free (not executed yet) function
+TDF_Label FThread::getFreeFunction()
+{
+    TDF_Label L;
+    TDF_ListIteratorOfLabelList itrl(itr.Current());
+    for (; itrl.More(); itrl.Next())
+    {
+        if (itr.GetStatus(itrl.Value()) == TFunction_ES_NotExecuted)
+        {
+            L = itrl.Value();
+            itr.SetStatus(L, TFunction_ES_Executing);
+            break;
+        }
+    }
+    return L;
+}
+
+void FThread::run()
+{
+    while (itr.More())
+    {
+        // Take current function,
+        // choose one and set its status to "executing".
+        TDF_Label L;
+        for (; itr.More(); itr.Next())
+        {
+            L = getFreeFunction();
+            if (L.IsNull())
+                ::Sleep(100);
+            else
+                break;
+        }
+
+        // Nothing to compute? Finish.
+        if (L.IsNull())
+        {
+            graph->setFinished();
+            return;
+        }
+
+        // Check a Tick attribute - a marker of skipped for execution functions.
+        // It is used only for visual presentation of skipped (not modified) functions.
+        Handle(TDataStd_Tick) tick;
+        if (L.FindAttribute(TDataStd_Tick::GetID(), tick))
+            L.ForgetAttribute(tick);
+
+        // Execute the function
+        Handle(TFunction_Driver) D = TFunction_IFunction(L).GetDriver(thread_index);
+        const bool must = D->MustExecute(log);
+        if (must)
+        {
+            // Usage of mutex for execution of Open CASCADE code is the most stupid thing!!!
+            // But it makes the execution more reliable...
+            const int ret = D->Execute(log);
+            if (ret == 0)
+            {
+                // Successfuly executed!
+                itr.SetStatus(L, TFunction_ES_Succeeded);
+
+                TDF_LabelList res;
+                D->Results(res);
+                TDF_ListIteratorOfLabelList itrr(res);
+                for (; itrr.More(); itrr.Next())
+                {
+                    log->SetImpacted(itrr.Value());
+                }
+            }
+            else
+            {
+                // Failed...
+                itr.SetStatus(L, TFunction_ES_Failed);
+                graph->setFinished();
+                return;
+            }
+        }
+        else if (itr.GetStatus(L) == TFunction_ES_Executing)
+        {
+            itr.SetStatus(L, TFunction_ES_Succeeded);
+            TDataStd_Tick::Set(L);
+        }
+
+    }// while (More())
+
+    graph->setFinished();
+}
\ No newline at end of file
diff --git a/samples/qt/FuncDemo/src/FThread.h b/samples/qt/FuncDemo/src/FThread.h
new file mode 100644 (file)
index 0000000..30bd270
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef _FTHREAD_H_
+#define _FTHREAD_H_
+
+#include <QThread>
+
+#include <TFunction_Logbook.hxx>
+#include <TFunction_Iterator.hxx>
+#include <TFunction_Driver.hxx>
+
+class GraphWidget; // shows graphically execution of functions
+
+class FThread : public QThread
+{
+
+    Q_OBJECT
+
+public:
+
+    FThread(QObject* parent = 0);
+    ~FThread();
+
+    void setIterator(const TFunction_Iterator& ); // to iterate and call functions
+    void setLogbook(const Handle(TFunction_Logbook)& );         // to set logbook with modifications
+    void setGraph(GraphWidget* );                 // to change color of a graph circle
+    void setThreadIndex(const int );              // to set the index of the thread
+
+protected:
+
+    void run();
+    virtual TDF_Label getFreeFunction();          // Returns any free (not executed yet) function
+
+private:
+
+    TFunction_Iterator itr;
+    Handle(TFunction_Logbook) log;
+    int                thread_index;
+
+    GraphWidget*       graph;
+};
+
+#endif // _FTHREAD_H_
\ No newline at end of file
diff --git a/samples/qt/FuncDemo/src/PointDriver.cpp b/samples/qt/FuncDemo/src/PointDriver.cpp
new file mode 100644 (file)
index 0000000..3f10412
--- /dev/null
@@ -0,0 +1,55 @@
+// PointDriver.cpp: implementation of the PointDriver class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "PointDriver.h"
+
+#include <Standard_GUID.hxx>
+#include <TDF_Reference.hxx>
+#include <TNaming_Builder.hxx>
+#include <TDataStd_RealArray.hxx>
+
+#include <gp_Pnt.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <BRepBuilderAPI_MakeVertex.hxx>
+
+IMPLEMENT_STANDARD_HANDLE(PointDriver,BaseDriver)
+IMPLEMENT_STANDARD_RTTIEXT(PointDriver,BaseDriver)
+
+// ID of the function driver
+const Standard_GUID& PointDriver::GetID()
+{
+    static const Standard_GUID id("E9467D43-B11D-42d3-AF10-E91B74D2A3D9");
+    return id;
+}
+
+// Constructor
+PointDriver::PointDriver()
+{
+
+}
+
+// Execution.
+Standard_Integer PointDriver::Execute(Handle(TFunction_Logbook)& log) const
+{
+    // Usual check...
+    if (Label().IsNull())
+        return 1;
+
+    // Take the arguments (x, y, z)
+    Handle(TDataStd_RealArray) arr;
+    if (!Label().FindAttribute(TDataStd_RealArray::GetID(), arr))
+        return 2;
+    double x = arr->Value(1);
+    double y = arr->Value(2);
+    double z = arr->Value(3);
+
+    // Make the result
+    TopoDS_Vertex V = BRepBuilderAPI_MakeVertex(gp_Pnt(x, y, z));
+
+    // Set the result
+    TNaming_Builder B(Label());
+    B.Generated(V);
+
+    return BaseDriver::Execute(log);
+}
\ No newline at end of file
diff --git a/samples/qt/FuncDemo/src/PointDriver.h b/samples/qt/FuncDemo/src/PointDriver.h
new file mode 100644 (file)
index 0000000..a71591b
--- /dev/null
@@ -0,0 +1,36 @@
+// PointDriver.h: interface for the Point function driver.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(_PointDRIVER_H_)
+#define _PointDRIVER_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "BaseDriver.h"
+
+#include <Standard_DefineHandle.hxx> 
+#include <TFunction_Logbook.hxx>
+
+DEFINE_STANDARD_HANDLE(PointDriver, BaseDriver)
+
+// A Point function driver.
+class PointDriver : public BaseDriver
+{
+public:
+
+    // ID of the function driver
+    static const Standard_GUID& GetID();
+    
+    // Constructor
+       PointDriver();
+
+       // Execution.
+       virtual Standard_Integer Execute(Handle(TFunction_Logbook)& log) const;
+
+       DEFINE_STANDARD_RTTIEXT(PointDriver, TFunction_Driver)
+};
+
+#endif // !defined(_PointDRIVER_H_)
diff --git a/samples/qt/FuncDemo/src/PrismDriver.cpp b/samples/qt/FuncDemo/src/PrismDriver.cpp
new file mode 100644 (file)
index 0000000..8f99551
--- /dev/null
@@ -0,0 +1,73 @@
+// PrismDriver.cpp: implementation of the PrismDriver class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "PrismDriver.h"
+
+#include <Standard_GUID.hxx>
+#include <TDF_Reference.hxx>
+#include <TNaming_Builder.hxx>
+#include <TNaming_NamedShape.hxx>
+#include <TDataStd_Real.hxx>
+
+#include <TopoDS.hxx>
+#include <TopoDS_Face.hxx>
+#include <BRepPrimAPI_MakePrism.hxx>
+#include <Precision.hxx>
+
+IMPLEMENT_STANDARD_HANDLE(PrismDriver,BaseDriver)
+IMPLEMENT_STANDARD_RTTIEXT(PrismDriver,BaseDriver)
+
+// ID of the function driver
+const Standard_GUID& PrismDriver::GetID()
+{
+    static const Standard_GUID id("D017489C-EFCE-4e57-8FE9-FA3DEF7DACA9");
+    return id;
+}
+
+// Constructor
+PrismDriver::PrismDriver()
+{
+
+}
+
+// Execution.
+Standard_Integer PrismDriver::Execute(Handle(TFunction_Logbook)& log) const
+{
+    // Usual check...
+    if (Label().IsNull())
+        return 1;
+
+    // Take the arguments (height)
+    Handle(TDataStd_Real) h;
+    if (!Label().FindAttribute(TDataStd_Real::GetID(), h))
+        return 2;
+    double height = h->Get();
+    if (height < Precision::Confusion())
+        return 3;
+
+    // Take the arguments (circular face)
+    Handle(TDF_Reference) ref;
+    TDF_Label Lcircle = Label().FindChild(1).FindChild(1);
+    if (!Lcircle.FindAttribute(TDF_Reference::GetID(), ref))
+        return 4;
+    Handle(TNaming_NamedShape) n;
+    if (!ref->Get().FindAttribute(TNaming_NamedShape::GetID(), n) || n->IsEmpty())
+        return 5;
+    TopoDS_Face F = TopoDS::Face(n->Get());
+
+    // Make the result
+    BRepPrimAPI_MakePrism mkPrism(F, gp_Vec(height * gp::DZ()));
+    if (!mkPrism.IsDone())
+        return 6;
+    TopoDS_Shape P = mkPrism.Shape();
+    TopoDS_Shape Top = mkPrism.LastShape();
+
+    // Set the result
+    TNaming_Builder B(Label());
+    B.Generated(P);
+    TNaming_Builder B2(Label().FindChild(3));
+    B2.Generated(Top);
+
+    return BaseDriver::Execute(log);
+}
\ No newline at end of file
diff --git a/samples/qt/FuncDemo/src/PrismDriver.h b/samples/qt/FuncDemo/src/PrismDriver.h
new file mode 100644 (file)
index 0000000..5f11dcb
--- /dev/null
@@ -0,0 +1,36 @@
+// PrismDriver.h: interface for the Prism function driver.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(_PRISMDRIVER_H_)
+#define _PRISMDRIVER_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "BaseDriver.h"
+
+#include <Standard_DefineHandle.hxx> 
+#include <TFunction_Logbook.hxx>
+
+DEFINE_STANDARD_HANDLE(PrismDriver, BaseDriver)
+
+// A Prism function driver.
+class PrismDriver : public BaseDriver
+{
+public:
+
+    // ID of the function driver
+    static const Standard_GUID& GetID();
+    
+    // Constructor
+       PrismDriver();
+
+       // Execution.
+       virtual Standard_Integer Execute(Handle(TFunction_Logbook)& log) const;
+
+       DEFINE_STANDARD_RTTIEXT(PrismDriver, TFunction_Driver)
+};
+
+#endif // !defined(_PRISMDRIVER_H_)
diff --git a/samples/qt/FuncDemo/src/ShapeSaverDriver.cpp b/samples/qt/FuncDemo/src/ShapeSaverDriver.cpp
new file mode 100644 (file)
index 0000000..1f14881
--- /dev/null
@@ -0,0 +1,65 @@
+// ShapeSaverDriver.cpp: implementation of the ShapeSaverDriver class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "ShapeSaverDriver.h"
+
+#include <Standard_GUID.hxx>
+#include <TopoDS_Compound.hxx>
+#include <TDF_ChildIterator.hxx>
+#include <TDF_Reference.hxx>
+#include <TNaming_Builder.hxx>
+#include <TNaming_NamedShape.hxx>
+#include <BRep_Builder.hxx>
+#include <BRepTools.hxx>
+
+IMPLEMENT_STANDARD_HANDLE(ShapeSaverDriver,BaseDriver)
+IMPLEMENT_STANDARD_RTTIEXT(ShapeSaverDriver,BaseDriver)
+
+// ID of the function driver
+const Standard_GUID& ShapeSaverDriver::GetID()
+{
+    static const Standard_GUID id("6B77A40E-E074-4fe1-AB9B-ECECA506717A");
+    return id;
+}
+
+// Constructor
+ShapeSaverDriver::ShapeSaverDriver()
+{
+
+}
+
+// Execution.
+Standard_Integer ShapeSaverDriver::Execute(Handle(TFunction_Logbook)& log) const
+{
+    // Usual check...
+    if (Label().IsNull())
+        return 1;
+
+    // A compound of results of all functions
+    TopoDS_Compound C;
+    BRep_Builder B;
+    B.MakeCompound(C);
+
+    // Take results of all functions
+    TDF_ChildIterator itr(Label().FindChild(1), false);
+    for (; itr.More(); itr.Next())
+    {
+        Handle(TDF_Reference) ref;
+        if (itr.Value().FindAttribute(TDF_Reference::GetID(), ref))
+        {
+            Handle(TNaming_NamedShape) n;
+            if (ref->Get().FindAttribute(TNaming_NamedShape::GetID(), n) && !n->IsEmpty())
+            {
+                B.Add(C, n->Get());
+            }
+        }
+    }
+
+    //BRepTools::Write(C, "result.brep");
+
+    TNaming_Builder Bui(Label());
+    Bui.Generated(C);
+
+    return BaseDriver::Execute(log);
+}
\ No newline at end of file
diff --git a/samples/qt/FuncDemo/src/ShapeSaverDriver.h b/samples/qt/FuncDemo/src/ShapeSaverDriver.h
new file mode 100644 (file)
index 0000000..cf3c399
--- /dev/null
@@ -0,0 +1,36 @@
+// ShapeSaverDriver.h: interface for the ShapeSaver function driver.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(_SHAPESAVERDRIVER_H_)
+#define _SHAPESAVERDRIVER_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "BaseDriver.h"
+
+#include <Standard_DefineHandle.hxx> 
+#include <TFunction_Logbook.hxx>
+
+DEFINE_STANDARD_HANDLE(ShapeSaverDriver, BaseDriver)
+
+// A ShapeSaver function driver.
+class ShapeSaverDriver : public BaseDriver
+{
+public:
+
+    // ID of the function driver
+    static const Standard_GUID& GetID();
+    
+    // Constructor
+       ShapeSaverDriver();
+
+       // Execution.
+       virtual Standard_Integer Execute(Handle(TFunction_Logbook)& log) const;
+
+       DEFINE_STANDARD_RTTIEXT(ShapeSaverDriver, TFunction_Driver)
+};
+
+#endif // !defined(_SHAPESAVERDRIVER_H_)
diff --git a/samples/qt/FuncDemo/src/SimpleDriver.cpp b/samples/qt/FuncDemo/src/SimpleDriver.cpp
new file mode 100644 (file)
index 0000000..0d42fc2
--- /dev/null
@@ -0,0 +1,85 @@
+// SimpleDriver.cpp: implementation of the SimpleDriver class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "SimpleDriver.h"
+
+#include <TDF_Reference.hxx>
+#include <TDF_ChildIterator.hxx>
+#include <Standard_GUID.hxx>
+#include <OSD_Timer.hxx>
+#include <TDataStd_Real.hxx>
+#include <BRepPrimAPI_MakeSphere.hxx>
+
+IMPLEMENT_STANDARD_HANDLE(SimpleDriver,  TFunction_Driver)
+IMPLEMENT_STANDARD_RTTIEXT(SimpleDriver, TFunction_Driver)
+
+// ID of the function driver
+const Standard_GUID& SimpleDriver::GetID()
+{
+    static const Standard_GUID id("4534840D-6DCD-440f-9F0E-BDEF1C50D434");
+    return id;
+}
+
+// Constructor
+SimpleDriver::SimpleDriver()
+{
+
+}
+
+// Returns the arguments of the function
+void SimpleDriver::Arguments(TDF_LabelList& args) const
+{
+    // A double - relative time of execution
+    args.Append(Label());
+
+    // References to other functions through TDF_Reference
+    TDF_ChildIterator itr(Label().FindChild(1), false);
+    for (; itr.More(); itr.Next())
+    {
+        Handle(TDF_Reference) ref;
+        if (itr.Value().FindAttribute(TDF_Reference::GetID(), ref))
+            args.Append(ref->Get());
+    }
+}
+
+
+// Returns the results of the function
+void SimpleDriver::Results(TDF_LabelList& res) const
+{
+    // References to other functions through TDF_Reference
+    res.Append(Label());
+    TDF_ChildIterator itr(Label().FindChild(2), false);
+    for (; itr.More(); itr.Next())
+    {
+        Handle(TDF_Reference) ref;
+        if (itr.Value().FindAttribute(TDF_Reference::GetID(), ref))
+            res.Append(ref->Get());
+    }
+}
+
+// Execution.
+Standard_Integer SimpleDriver::Execute(Handle(TFunction_Logbook)& log) const
+{
+       // Check initialization
+       if (Label().IsNull())
+               return 1;
+
+    // Take the double argument
+    Handle(TDataStd_Real) time_keeper;
+    if (!Label().FindAttribute(TDataStd_Real::GetID(), time_keeper))
+        return 2;
+    double times = time_keeper->Get();
+
+    // Make a sphere 10000 * "times" times (it takes about a second on a simple computer).
+    int i = 0;
+    while (++i < 10000 * times)
+    {
+        // Call any fucntions taking much time.
+        // It is necessary to "see" the execution of a function in real time.
+        BRepPrimAPI_MakeSphere mkSphere(100.0);
+        mkSphere.Build();
+    }
+
+    return 0;
+}
\ No newline at end of file
diff --git a/samples/qt/FuncDemo/src/SimpleDriver.h b/samples/qt/FuncDemo/src/SimpleDriver.h
new file mode 100644 (file)
index 0000000..a78a065
--- /dev/null
@@ -0,0 +1,42 @@
+// SimpleDriver.h: interface for the Simple function driver.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(_SIMPLEDRIVER_H_)
+#define _SIMPLEDRIVER_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include <Standard_DefineHandle.hxx> 
+#include <TFunction_Driver.hxx>
+#include <TFunction_Logbook.hxx>
+#include <TDF_LabelList.hxx>
+
+DEFINE_STANDARD_HANDLE(SimpleDriver, TFunction_Driver)
+
+// A function driver for a Simple function.
+class SimpleDriver : public TFunction_Driver
+{
+public:
+
+    // ID of the function driver
+    static const Standard_GUID& GetID();
+    
+    // Constructor
+       SimpleDriver();
+
+       // Returns the arguments of the function
+       virtual void Arguments(TDF_LabelList& args) const;
+
+       // Returns the results of the function
+       virtual void Results(TDF_LabelList& res) const;
+
+       // Execution.
+       virtual Standard_Integer Execute(Handle(TFunction_Logbook)& log) const;
+
+       DEFINE_STANDARD_RTTIEXT(SimpleDriver, TFunction_Driver)
+};
+
+#endif // !defined(_SIMPLEDRIVER_H_)
diff --git a/samples/qt/FuncDemo/src/edge.cpp b/samples/qt/FuncDemo/src/edge.cpp
new file mode 100644 (file)
index 0000000..c50b5b6
--- /dev/null
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2006-2007 Trolltech ASA. All rights reserved.
+**
+** This file is part of the example classes of the Qt Toolkit.
+**
+** Licensees holding a valid Qt License Agreement may use this file in
+** accordance with the rights, responsibilities and obligations
+** contained therein.  Please consult your licensing agreement or
+** contact sales@trolltech.com if any conditions of this licensing
+** agreement are not clear to you.
+**
+** Further information about Qt licensing is available at:
+** http://www.trolltech.com/products/qt/licensing.html or by
+** contacting info@trolltech.com.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#include <QPainter>
+
+#include "edge.h"
+#include "node.h"
+
+#include <math.h>
+
+static const double Pi = 3.14159265358979323846264338327950288419717;
+static double TwoPi = 2.0 * Pi;
+
+Edge::Edge(Node *sourceNode, Node *destNode)
+    : arrowSize(10)
+{
+    setAcceptedMouseButtons(0);
+    source = sourceNode;
+    dest = destNode;
+    source->addEdge(this);
+    dest->addEdge(this);
+    adjust();
+}
+
+Edge::~Edge()
+{
+}
+
+Node *Edge::sourceNode() const
+{
+    return source;
+}
+
+void Edge::setSourceNode(Node *node)
+{
+    source = node;
+    adjust();
+}
+
+Node *Edge::destNode() const
+{
+    return dest;
+}
+
+void Edge::setDestNode(Node *node)
+{
+    dest = node;
+    adjust();
+}
+
+void Edge::adjust()
+{
+    if (!source || !dest)
+        return;
+
+    QLineF line(mapFromItem(source, 0, 0), mapFromItem(dest, 0, 0));
+    qreal length = line.length();
+    QPointF edgeOffset((line.dx() * 15) / length, (line.dy() * 15) / length);
+
+    prepareGeometryChange();
+    sourcePoint = line.p1() + edgeOffset;
+    destPoint = line.p2() - edgeOffset;
+}
+
+QRectF Edge::boundingRect() const
+{
+    if (!source || !dest)
+        return QRectF();
+
+    qreal penWidth = 1;
+    qreal extra = (penWidth + arrowSize) / 2.0;
+
+    return QRectF(sourcePoint, QSizeF(destPoint.x() - sourcePoint.x(),
+                                      destPoint.y() - sourcePoint.y()))
+        .normalized()
+        .adjusted(-extra, -extra, extra, extra);
+}
+
+void Edge::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
+{
+    if (!source || !dest)
+        return;
+
+    adjust();
+
+    // Draw the line itself
+    QLineF line(sourcePoint, destPoint);
+    painter->setPen(QPen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
+    painter->drawLine(line);
+
+    // Draw the arrows if there's enough room
+    double angle = ::acos(line.dx() / line.length());
+    if (line.dy() >= 0)
+        angle = TwoPi - angle;
+
+    QPointF destArrowP1 = destPoint + QPointF(sin(angle - Pi / 3) * arrowSize,
+                                              cos(angle - Pi / 3) * arrowSize);
+    QPointF destArrowP2 = destPoint + QPointF(sin(angle - Pi + Pi / 3) * arrowSize,
+                                              cos(angle - Pi + Pi / 3) * arrowSize);
+
+    painter->setBrush(Qt::black);
+    painter->drawPolygon(QPolygonF() << line.p2() << destArrowP1 << destArrowP2);        
+}
diff --git a/samples/qt/FuncDemo/src/edge.h b/samples/qt/FuncDemo/src/edge.h
new file mode 100644 (file)
index 0000000..1d2ac27
--- /dev/null
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2006-2007 Trolltech ASA. All rights reserved.
+**
+** This file is part of the example classes of the Qt Toolkit.
+**
+** Licensees holding a valid Qt License Agreement may use this file in
+** accordance with the rights, responsibilities and obligations
+** contained therein.  Please consult your licensing agreement or
+** contact sales@trolltech.com if any conditions of this licensing
+** agreement are not clear to you.
+**
+** Further information about Qt licensing is available at:
+** http://www.trolltech.com/products/qt/licensing.html or by
+** contacting info@trolltech.com.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#ifndef EDGE_H
+#define EDGE_H
+
+#include <QGraphicsItem>
+
+class Node;
+
+class Edge : public QGraphicsItem
+{
+public:
+    Edge(Node *sourceNode, Node *destNode);
+    ~Edge();
+
+    Node *sourceNode() const;
+    void setSourceNode(Node *node);
+
+    Node *destNode() const;
+    void setDestNode(Node *node);
+
+    void adjust();
+
+    enum { Type = UserType + 2 };
+    int type() const { return Type; }
+    
+protected:
+    QRectF boundingRect() const;
+    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+    
+private:
+    Node *source, *dest;
+
+    QPointF sourcePoint;
+    QPointF destPoint;
+    qreal arrowSize;
+};
+
+#endif
diff --git a/samples/qt/FuncDemo/src/graphwidget.cpp b/samples/qt/FuncDemo/src/graphwidget.cpp
new file mode 100644 (file)
index 0000000..588ee5e
--- /dev/null
@@ -0,0 +1,392 @@
+/****************************************************************************
+**
+** Copyright (C) 2006-2007 Trolltech ASA. All rights reserved.
+**
+** This file is part of the example classes of the Qt Toolkit.
+**
+** Licensees holding a valid Qt License Agreement may use this file in
+** accordance with the rights, responsibilities and obligations
+** contained therein.  Please consult your licensing agreement or
+** contact sales@trolltech.com if any conditions of this licensing
+** agreement are not clear to you.
+**
+** Further information about Qt licensing is available at:
+** http://www.trolltech.com/products/qt/licensing.html or by
+** contacting info@trolltech.com.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#include "graphwidget.h"
+#include "edge.h"
+#include "node.h"
+
+#include <QDebug>
+#include <QGraphicsScene>
+#include <QWheelEvent>
+#include <QApplication>
+
+#include <math.h>
+
+#include <TFunction_Iterator.hxx>
+#include <TFunction_IFunction.hxx>
+#include <TFunction_GraphNode.hxx>
+#include <TFunction_Scope.hxx>
+#include <TFunction_DriverTable.hxx>
+#include <TFunction_Driver.hxx>
+#include <TFunction_Function.hxx>
+
+#include <TDataStd_Name.hxx>
+#include <TDF_ChildIterator.hxx>
+#include <TDF_ListIteratorOfLabelList.hxx>
+#include <TColStd_MapIteratorOfMapOfInteger.hxx>
+
+#include "SimpleDriver.h"
+#include "PointDriver.h"
+#include "CircleDriver.h"
+#include "PrismDriver.h"
+#include "ConeDriver.h"
+#include "CylinderDriver.h"
+#include "ShapeSaverDriver.h"
+#include "SimpleDriver.h"
+
+GraphWidget::GraphWidget(QWidget* parent):QGraphicsView(parent),
+    myThread1(0),myThread2(0),myThread3(0),myThread4(0)
+{
+    QGraphicsScene *scene = new QGraphicsScene(this);
+    scene->setItemIndexMethod(QGraphicsScene::NoIndex);
+    scene->setSceneRect(1, 1, parent->width(), parent->height());
+    setScene(scene);
+    setCacheMode(CacheBackground);
+    setRenderHint(QPainter::Antialiasing);
+    setTransformationAnchor(AnchorUnderMouse);
+    setResizeAnchor(AnchorViewCenter);
+
+    scale(0.7, 0.81);
+    setMinimumSize(400, 400);
+    setWindowTitle(tr("Function Mechanism"));
+
+    setNbThreads(1);
+}
+
+GraphWidget::~GraphWidget()
+{
+    if (myThread1)
+    {
+        myThread1->wait();
+        myThread1->deleteLater();
+    }
+    if (myThread2)
+    {
+        myThread2->wait();
+        myThread2->deleteLater();
+    }
+    if (myThread3)
+    {
+        myThread3->wait();
+        myThread3->deleteLater();
+    }
+    if (myThread4)
+    {
+        myThread4->wait();
+        myThread4->deleteLater();
+    }
+}
+
+bool GraphWidget::createModel(const Handle(TDocStd_Document)& doc)
+{
+    myDocument = doc;
+    
+    TFunction_Iterator fIterator(myDocument->Main());
+    fIterator.SetUsageOfExecutionStatus(false);
+    Handle(TFunction_Scope) scope = TFunction_Scope::Set(myDocument->Main());
+
+    // Find out the size of the grid: number of functions in X and Y directions
+    int nbx = 0, nby = 0;
+    while (!fIterator.Current().IsEmpty())
+    {
+        const TDF_LabelList& funcs = fIterator.Current();
+        if (funcs.Extent() > nbx)
+            nbx = funcs.Extent();
+        nby++;
+        fIterator.Next();
+    }
+    if (!nbx || !nby)
+        return false;
+
+    // Grid of functions
+    int dx = width() / nbx, dy = height() / nby;
+    int x0 = dx / 2, y0 = dy / 2; // start position
+
+    // Draw functions
+    double x = x0, y = y0;
+    fIterator.Init(myDocument->Main());
+    while (!fIterator.Current().IsEmpty())
+    {
+        const TDF_LabelList& funcs = fIterator.Current();
+        TDF_ListIteratorOfLabelList itrl(funcs);
+        for (; itrl.More(); itrl.Next())
+        {
+            TDF_Label L = itrl.Value();
+            Node *node = new Node(this);
+            node->setFunction(L);
+            scene()->addItem(node);
+            node->setPos(x, y);
+            x += dx;
+            if (x > width())
+                x = x0;
+        }
+        y += dy;
+        if (y > height())
+            y = y0;
+        fIterator.Next();
+    }
+
+    // Draw dependencies
+    fIterator.Init(myDocument->Main());
+    while (!fIterator.Current().IsEmpty())
+    {
+        const TDF_LabelList& funcs = fIterator.Current();
+        TDF_ListIteratorOfLabelList itrl(funcs);
+        for (; itrl.More(); itrl.Next())
+        {
+            TDF_Label L = itrl.Value();
+            Node* node = findNode(L);
+            if (!node)
+                continue;
+
+            // Find backward dependencies of the function
+            TFunction_IFunction iFunc(L);
+            Handle(TFunction_GraphNode) graphNode = iFunc.GetGraphNode();
+            const TColStd_MapOfInteger& prev = graphNode->GetPrevious();
+            TColStd_MapIteratorOfMapOfInteger itrm(prev);
+            for (; itrm.More(); itrm.Next())
+            {
+                const int argID = itrm.Key();
+                const TDF_Label& argL = scope->GetFunction(argID);
+                Node* n = findNode(argL);
+                if (!n)
+                    continue;
+                scene()->addItem(new Edge(n, node));
+            }
+        }
+        fIterator.Next();
+    }
+
+    return !myDocument.IsNull();
+}
+
+void GraphWidget::wheelEvent(QWheelEvent *event)
+{
+    scaleView(pow((double)2, -event->delta() / 240.0));
+}
+
+void GraphWidget::drawBackground(QPainter *painter, const QRectF &rect)
+{
+    Q_UNUSED(rect);
+
+    // Shadow
+    QRectF sceneRect = this->sceneRect();
+    QRectF rightShadow(sceneRect.right(), sceneRect.top() + 5, 5, sceneRect.height());
+    QRectF bottomShadow(sceneRect.left() + 5, sceneRect.bottom(), sceneRect.width(), 5);
+    if (rightShadow.intersects(rect) || rightShadow.contains(rect))
+       painter->fillRect(rightShadow, Qt::darkGray);
+    if (bottomShadow.intersects(rect) || bottomShadow.contains(rect))
+       painter->fillRect(bottomShadow, Qt::darkGray);
+
+    // Fill
+    QLinearGradient gradient(sceneRect.topLeft(), sceneRect.bottomRight());
+    gradient.setColorAt(0, Qt::white);
+    gradient.setColorAt(1, Qt::lightGray);
+    painter->fillRect(rect.intersect(sceneRect), gradient);
+    painter->setBrush(Qt::NoBrush);
+    painter->drawRect(sceneRect);
+}
+
+void GraphWidget::scaleView(qreal scaleFactor)
+{
+    qreal factor = matrix().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width();
+    if (factor < 0.07 || factor > 100)
+        return;
+
+    scale(scaleFactor, scaleFactor);
+}
+
+// Find node of the function
+Node* GraphWidget::findNode(const TDF_Label& L)
+{
+    Node* node = 0;
+    for (int i = 0; i < scene()->items().size(); i++)
+    {
+        Node* n = qgraphicsitem_cast<Node *>(scene()->items().at(i));
+        if (n && n->getFunction() == L)
+        {
+            node = n;
+            break;
+        }
+    }
+    return node;
+}
+
+void GraphWidget::compute()
+{
+    myNbFinishedThreads = 0;
+
+    TFunction_Iterator fIterator(myDocument->Main());
+    fIterator.SetUsageOfExecutionStatus(true);
+
+    myThread1 = new FThread();
+    if (myNbThreads > 1)
+        myThread2 = new FThread();
+    if (myNbThreads > 2)
+        myThread3 = new FThread();
+    if (myNbThreads > 3)
+        myThread4 = new FThread();
+
+    // Logbook
+    Handle(TFunction_Logbook) log = TFunction_Scope::Set(myDocument->Main())->GetLogbook();
+    myThread1->setLogbook(log);
+    if (myNbThreads > 1)
+        myThread2->setLogbook(log);
+    if (myNbThreads > 2)
+        myThread3->setLogbook(log);
+    if (myNbThreads > 3)
+        myThread4->setLogbook(log);
+
+    myThread1->setIterator(fIterator);
+    if (myNbThreads > 1)
+        myThread2->setIterator(fIterator);
+    if (myNbThreads > 2)
+        myThread3->setIterator(fIterator);
+    if (myNbThreads > 3)
+        myThread4->setIterator(fIterator);
+
+    myThread1->setGraph(this);
+    if (myNbThreads > 1)
+        myThread2->setGraph(this);
+    if (myNbThreads > 2)
+        myThread3->setGraph(this);
+    if (myNbThreads > 3)
+        myThread4->setGraph(this);
+
+    myThread1->setThreadIndex(1);
+    if (myNbThreads > 1)
+        myThread2->setThreadIndex(2);
+    if (myNbThreads > 2)
+        myThread3->setThreadIndex(3);
+    if (myNbThreads > 3)
+        myThread4->setThreadIndex(4);
+
+    QThread::Priority priority = QThread::LowestPriority;
+    if (!myThread1->isRunning())
+        myThread1->start(priority);
+    if (myNbThreads > 1 && !myThread2->isRunning())
+        myThread2->start(priority);
+    if (myNbThreads > 2 && !myThread3->isRunning())
+        myThread3->start(priority);
+    if (myNbThreads > 3 && !myThread4->isRunning())
+        myThread4->start(priority);
+}
+
+void GraphWidget::setNbThreads(const int nb)
+{
+    myNbThreads = nb;
+    if (myNbThreads < 4 && myThread4)
+    {
+        myThread4->wait();
+        myThread4->deleteLater();
+        myThread4 = 0;
+    }
+    if (myNbThreads < 3 && myThread3)
+    {
+        myThread3->wait();
+        myThread3->deleteLater();
+        myThread3 = 0;
+    }
+    if (myNbThreads < 2 && myThread2)
+    {
+        myThread2->wait();
+        myThread2->deleteLater();
+        myThread2 = 0;
+    }
+
+    for (int i = 1; i <= myNbThreads; i++)
+    {
+        TFunction_DriverTable::Get()->AddDriver(PointDriver::GetID(), new PointDriver(), i);
+        TFunction_DriverTable::Get()->AddDriver(CircleDriver::GetID(), new CircleDriver(), i);
+        TFunction_DriverTable::Get()->AddDriver(PrismDriver::GetID(), new PrismDriver(), i);
+        TFunction_DriverTable::Get()->AddDriver(ConeDriver::GetID(), new ConeDriver(), i);
+        TFunction_DriverTable::Get()->AddDriver(CylinderDriver::GetID(), new CylinderDriver(), i);
+        TFunction_DriverTable::Get()->AddDriver(ShapeSaverDriver::GetID(), new ShapeSaverDriver(), i);
+        TFunction_DriverTable::Get()->AddDriver(SimpleDriver::GetID(), new SimpleDriver(), i);
+    }
+}
+
+int GraphWidget::getNbThreads()
+{
+    return myNbThreads;
+}
+
+void GraphWidget::setFinished()
+{
+    myNbFinishedThreads++;
+}
+
+bool GraphWidget::isFinished()
+{
+    return myNbThreads == myNbFinishedThreads ;
+}
+
+void GraphWidget::accelerateThread(const int thread_index)
+{
+    bool all_slow = true;
+    if (myThread1 && myThread1->priority() != QThread::LowPriority)
+        all_slow = false;
+    if (all_slow && myThread2 && myThread2->priority() != QThread::LowPriority)
+        all_slow = false;
+    if (all_slow && myThread3 && myThread3->priority() != QThread::LowPriority)
+        all_slow = false;
+    if (all_slow && myThread4 && myThread4->priority() != QThread::LowPriority)
+        all_slow = false;
+    if (!all_slow)
+        return;
+
+    QThread::Priority priority = QThread::NormalPriority;
+    switch (thread_index)
+    {
+    case 1:
+        myThread1->setPriority(priority);
+        break;
+    case 2:
+        myThread2->setPriority(priority);
+        break;
+    case 3:
+        myThread3->setPriority(priority);
+        break;
+    case 4:
+        myThread4->setPriority(priority);
+        break;
+    }
+}
+
+void GraphWidget::slowDownThread(const int thread_index)
+{
+    QThread::Priority priority = QThread::LowPriority;
+    switch (thread_index)
+    {
+    case 1:
+        myThread1->setPriority(priority);
+        break;
+    case 2:
+        myThread2->setPriority(priority);
+        break;
+    case 3:
+        myThread3->setPriority(priority);
+        break;
+    case 4:
+        myThread4->setPriority(priority);
+        break;
+    }
+}
\ No newline at end of file
diff --git a/samples/qt/FuncDemo/src/graphwidget.h b/samples/qt/FuncDemo/src/graphwidget.h
new file mode 100644 (file)
index 0000000..1f4d63f
--- /dev/null
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2006-2007 Trolltech ASA. All rights reserved.
+**
+** This file is part of the example classes of the Qt Toolkit.
+**
+** Licensees holding a valid Qt License Agreement may use this file in
+** accordance with the rights, responsibilities and obligations
+** contained therein.  Please consult your licensing agreement or
+** contact sales@trolltech.com if any conditions of this licensing
+** agreement are not clear to you.
+**
+** Further information about Qt licensing is available at:
+** http://www.trolltech.com/products/qt/licensing.html or by
+** contacting info@trolltech.com.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#ifndef GRAPHWIDGET_H
+#define GRAPHWIDGET_H
+
+#include <QtGui/QGraphicsView>
+
+#include "FThread.h"
+
+#include <TDocStd_Document.hxx>
+#include <TDF_Label.hxx>
+
+class Node;
+
+class GraphWidget : public QGraphicsView
+{
+    Q_OBJECT
+
+public:
+    GraphWidget(QWidget* parent);
+    ~GraphWidget();
+    
+    bool createModel(const Handle(TDocStd_Document)& doc);
+    Handle(TDocStd_Document) getDocument() { return myDocument; }
+
+    Node* findNode(const TDF_Label& );
+    void  setNbThreads(const int nb);
+    int   getNbThreads();
+    void  accelerateThread(const int thread_index);
+    void  slowDownThread(const int thread_index);
+    void  compute();
+
+    void setFinished();
+    bool isFinished();
+
+protected:
+    void wheelEvent(QWheelEvent *event);
+    void drawBackground(QPainter *painter, const QRectF &rect);
+    void scaleView(qreal scaleFactor);
+
+private:
+    Handle(TDocStd_Document) myDocument;
+    int                      myNbThreads;
+    FThread*                 myThread1;
+    FThread*                 myThread2;
+    FThread*                 myThread3;
+    FThread*                 myThread4;
+    int                      myNbFinishedThreads;
+};
+
+#endif
diff --git a/samples/qt/FuncDemo/src/main.cpp b/samples/qt/FuncDemo/src/main.cpp
new file mode 100644 (file)
index 0000000..67dcfd8
--- /dev/null
@@ -0,0 +1,31 @@
+/****************************************************************************
+**
+** Copyright (C) 2004-2007 Trolltech ASA. All rights reserved.
+**
+** This file is part of the example classes of the Qt Toolkit.
+**
+** Licensees holding a valid Qt License Agreement may use this file in
+** accordance with the rights, responsibilities and obligations
+** contained therein.  Please consult your licensing agreement or
+** contact sales@trolltech.com if any conditions of this licensing
+** agreement are not clear to you.
+**
+** Further information about Qt licensing is available at:
+** http://www.trolltech.com/products/qt/licensing.html or by
+** contacting info@trolltech.com.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#include <QApplication>
+#include "mainwindow.h"
+
+int main(int argc, char *argv[])
+{
+    QApplication app(argc, argv);
+    MainWindow mainWin;
+    mainWin.show();
+    return app.exec();
+}
diff --git a/samples/qt/FuncDemo/src/mainwindow.cpp b/samples/qt/FuncDemo/src/mainwindow.cpp
new file mode 100644 (file)
index 0000000..2122279
--- /dev/null
@@ -0,0 +1,663 @@
+/****************************************************************************
+**
+** Copyright (C) 2004-2007 Trolltech ASA. All rights reserved.
+**
+** This file is part of the example classes of the Qt Toolkit.
+**
+** Licensees holding a valid Qt License Agreement may use this file in
+** accordance with the rights, responsibilities and obligations
+** contained therein.  Please consult your licensing agreement or
+** contact sales@trolltech.com if any conditions of this licensing
+** agreement are not clear to you.
+**
+** Further information about Qt licensing is available at:
+** http://www.trolltech.com/products/qt/licensing.html or by
+** contacting info@trolltech.com.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#include <QtGui>
+
+#include "mainwindow.h"
+#include "graphwidget.h"
+#include "node.h"
+#include "edge.h"
+
+#include "SimpleDriver.h"
+#include "PointDriver.h"
+#include "CircleDriver.h"
+#include "PrismDriver.h"
+#include "ConeDriver.h"
+#include "CylinderDriver.h"
+#include "ShapeSaverDriver.h"
+
+#include <TDocStd_Document.hxx>
+#include <TFunction_DriverTable.hxx>
+#include <TFunction_IFunction.hxx>
+#include <TFunction_GraphNode.hxx>
+#include <TFunction_DoubleMapOfIntegerLabel.hxx>
+#include <TFunction_DoubleMapIteratorOfDoubleMapOfIntegerLabel.hxx>
+#include <TFunction_Scope.hxx>
+
+#include <TColStd_MapIteratorOfMapOfInteger.hxx>
+#include <OSD_Timer.hxx>
+
+#include <TDF_Tool.hxx>
+#include <TDF_Reference.hxx>
+#include <TDF_MapIteratorOfLabelMap.hxx>
+#include <TDF_ListIteratorOfLabelList.hxx>
+#include <TDF_ChildIterator.hxx>
+
+#include <TDataStd_Name.hxx>
+#include <TDataStd_Real.hxx>
+#include <TDataStd_RealArray.hxx>
+
+MainWindow::MainWindow()
+{
+    graph = new GraphWidget(this);
+    setCentralWidget(graph);
+
+    createActions();
+    createMenus();
+    createToolBars();
+    createStatusBar();
+
+    // Create a new document
+    createDefaultModel1();
+}
+
+Handle(AppStd_Application) MainWindow::getApplication()
+{
+    if (gApplication.IsNull())
+        gApplication = new AppStd_Application();
+    return gApplication;
+}
+
+void MainWindow::closeEvent(QCloseEvent *event)
+{
+    event->accept();
+}
+
+void MainWindow::model1()
+{
+    // Clean the view
+    if (!graph->getDocument().IsNull())
+    {
+        QList<QGraphicsItem*> items = graph->scene()->items();
+        for (int i = 0; i < items.size(); i++)
+        {
+            QGraphicsItem* item = items.at(i);
+            graph->scene()->removeItem(item);
+        }
+    
+        // Close the document
+        getApplication()->Close(graph->getDocument());
+    }
+
+    // Create a new document
+    createDefaultModel1();
+}
+
+void MainWindow::model2()
+{
+    // Clean the view
+    if (!graph->getDocument().IsNull())
+    {
+        QList<QGraphicsItem*> items = graph->scene()->items();
+        for (int i = 0; i < items.size(); i++)
+        {
+            QGraphicsItem* item = items.at(i);
+            graph->scene()->removeItem(item);
+        }
+    
+        // Close the document
+        getApplication()->Close(graph->getDocument());
+    }
+
+    // Create a new document
+    createDefaultModel2();
+}
+
+static void prepareFunctions(GraphWidget* graph)
+{
+    if (!graph->getDocument().IsNull())
+    {
+        TDF_Label L = graph->getDocument()->Main().Root();
+        TDF_ChildIterator itr(L, true);
+        for (; itr.More(); itr.Next())
+        {
+            Handle(TFunction_GraphNode) G;
+            if (itr.Value().FindAttribute(TFunction_GraphNode::GetID(), G))
+            {
+                G->SetStatus(TFunction_ES_NotExecuted);
+            }
+        }
+    }
+}
+
+// Redraw the nodes (change their colour).            
+void MainWindow::redrawGraph()
+{
+    QList<QGraphicsItem*> items = graph->scene()->items();
+    for (int i = 0; i < items.size(); i++)
+    {
+        QGraphicsItem* item = items.at(i);
+        item->update();
+    }
+}
+
+void MainWindow::compute()
+{
+    OSD_Timer aTimer;
+    double seconds, CPUTime;
+    int hours, minutes;
+    aTimer.Start();
+
+    int i = 0, nb = 1; // number of repetitions (for test-purpose).
+
+    // Run computation
+    while (i++ < nb)
+    {
+        prepareFunctions(graph);
+        graph->compute();
+
+        while (!graph->isFinished())
+        {
+            // Redraw the nodes (change their colour).            
+            redrawGraph();
+
+            // Process user-events.
+            qApp->processEvents();
+            ::Sleep(100);
+        }
+    }
+
+    aTimer.Show(seconds, minutes, hours, CPUTime);
+    cout << "Execution of "<<graph->getNbThreads()<< " threads took          " << hours << " hours, " << minutes << " minutes, " << seconds << " seconds" << endl;
+
+    // Redraw the nodes (change their colour).            
+    redrawGraph();
+}
+
+void MainWindow::nbThreads()
+{
+    bool ok;
+    int nb = QInputDialog::getInteger(this, tr("Number of threads"), tr("(1 - 4): "), 
+                                      graph->getNbThreads(), 1, 4, 1, &ok);
+    if (ok)
+        graph->setNbThreads(nb);
+}
+
+void MainWindow::about()
+{
+   QMessageBox::about(this, tr("Test-application of the advanced Function Mechanism"),
+                      tr("The <b>Application</b> runs different models "
+                      "in single and multi-threaded modes. "
+                      "It shows graphically the result of computation."));
+}
+
+void MainWindow::createActions()
+{
+    model1Act = new QAction(QIcon("images/open.png"), tr("Model 1"), this);
+    model1Act->setStatusTip(tr("Model 1"));
+    connect(model1Act, SIGNAL(triggered()), this, SLOT(model1()));
+
+    model2Act = new QAction(QIcon("images/open.png"), tr("Model 2"), this);
+    model2Act->setStatusTip(tr("Model 2"));
+    connect(model2Act, SIGNAL(triggered()), this, SLOT(model2()));
+
+    computeAct = new QAction(QIcon("images/new.png"), tr("Compute"), this);
+    computeAct->setStatusTip(tr("Compute"));
+    connect(computeAct, SIGNAL(triggered()), this, SLOT(compute()));
+
+    nbThreadsAct = new QAction(tr("Number of threads"), this);
+    nbThreadsAct->setStatusTip(tr("Number of threads"));
+    connect(nbThreadsAct, SIGNAL(triggered()), this, SLOT(nbThreads()));
+
+    exitAct = new QAction(tr("E&xit"), this);
+    exitAct->setShortcut(tr("Ctrl+Q"));
+    exitAct->setStatusTip(tr("Exit the application"));
+    connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
+
+    aboutAct = new QAction(tr("&About"), this);
+    aboutAct->setStatusTip(tr("Show the application's About box"));
+    connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
+}
+
+void MainWindow::createMenus()
+{
+    computeMenu = menuBar()->addMenu(tr("&Model"));
+    computeMenu->addAction(model1Act);
+    computeMenu->addAction(model2Act);
+    computeMenu->addSeparator();
+    computeMenu->addAction(computeAct);
+    computeMenu->addAction(nbThreadsAct);
+    computeMenu->addSeparator();
+    computeMenu->addAction(exitAct);
+
+    menuBar()->addSeparator();
+
+    helpMenu = menuBar()->addMenu(tr("&Help"));
+    helpMenu->addAction(aboutAct);
+}
+
+void MainWindow::createToolBars()
+{
+    computeToolBar = addToolBar(tr("Model"));
+    computeToolBar->addAction(model1Act);
+    computeToolBar->addAction(model2Act);
+    computeToolBar->addAction(computeAct);
+}
+
+void MainWindow::createStatusBar()
+{
+    statusBar()->showMessage(tr("Ready"));
+}
+
+void MainWindow::createDefaultModel1()
+{
+    Handle(AppStd_Application) app = MainWindow::getApplication();
+    Handle(TDocStd_Document) doc;
+    app->NewDocument("XmlOcaf", doc);
+    TDF_Label mainLabel = doc->Main();
+
+    // Initialize function drivers
+    TFunction_DriverTable::Get()->AddDriver(SimpleDriver::GetID(), new SimpleDriver());
+
+    // Set a logbook.
+    Handle(TFunction_Logbook) logbook = TFunction_Logbook::Set(mainLabel);
+
+    // Create a tree of functions
+    TDF_Label L1 = mainLabel.FindChild(1);
+    TDF_Label L2 = mainLabel.FindChild(2);
+    TDF_Label L3 = mainLabel.FindChild(3);
+    TDF_Label L4 = mainLabel.FindChild(4);
+    TDF_Label L5 = mainLabel.FindChild(5);
+    TDF_Label L6 = mainLabel.FindChild(6);
+    TDF_Label L7 = mainLabel.FindChild(7);
+    double time = 2;
+    // 1:
+    TFunction_IFunction::NewFunction(L1, SimpleDriver::GetID());
+    TDataStd_Name::Set(L1, "1");
+    TDataStd_Real::Set(L1, time); // Argument
+    TDF_Reference::Set(L1.FindChild(2).FindChild(1), L1); // Result
+    TFunction_IFunction iFunc1(L1);
+    iFunc1.GetGraphNode()->SetStatus(TFunction_ES_NotExecuted);
+    // 2:
+    TFunction_IFunction::NewFunction(L2, SimpleDriver::GetID());
+    TDataStd_Name::Set(L2, "2");
+    TDataStd_Real::Set(L2, time); // Argument
+    TDF_Reference::Set(L2.FindChild(2).FindChild(1), L2); // Result
+    TFunction_IFunction iFunc2(L2);
+    iFunc2.GetGraphNode()->SetStatus(TFunction_ES_NotExecuted);
+    // 3:
+    TFunction_IFunction::NewFunction(L3, SimpleDriver::GetID());
+    TDataStd_Name::Set(L3, "3");
+    TDataStd_Real::Set(L3, time); // Argument
+    TDF_Reference::Set(L3.FindChild(1).FindChild(1), L1); // Argument: F3 -> F1
+    TDF_Reference::Set(L3.FindChild(2).FindChild(1), L3); // Result
+    TFunction_IFunction iFunc3(L3);
+    iFunc3.GetGraphNode()->SetStatus(TFunction_ES_NotExecuted);
+    // 4:
+    TFunction_IFunction::NewFunction(L4, SimpleDriver::GetID());
+    TDataStd_Name::Set(L4, "4");
+    TDataStd_Real::Set(L4, time); // Argument
+    TDF_Reference::Set(L4.FindChild(1).FindChild(1), L2); // Argument F4 -> F2
+    TDF_Reference::Set(L4.FindChild(1).FindChild(2), L3); // Argument F4 -> F3
+    TDF_Reference::Set(L4.FindChild(2).FindChild(1), L4); // Result
+    TFunction_IFunction iFunc4(L4);
+    iFunc4.GetGraphNode()->SetStatus(TFunction_ES_NotExecuted);
+    // 5:
+    TFunction_IFunction::NewFunction(L5, SimpleDriver::GetID());
+    TDataStd_Name::Set(L5, "5");
+    TDataStd_Real::Set(L5, time); // Argument
+    TDF_Reference::Set(L5.FindChild(1).FindChild(1), L4); // Argument F5 -> F4
+    TDF_Reference::Set(L5.FindChild(2).FindChild(1), L5); // Result
+    TFunction_IFunction iFunc5(L5);
+    iFunc5.GetGraphNode()->SetStatus(TFunction_ES_NotExecuted);
+    // 6:
+    TFunction_IFunction::NewFunction(L6, SimpleDriver::GetID());
+    TDataStd_Name::Set(L6, "6");
+    TDataStd_Real::Set(L6, time); // Argument
+    TDF_Reference::Set(L6.FindChild(1).FindChild(1), L4); // Argument F6 ->F4
+    TDF_Reference::Set(L6.FindChild(2).FindChild(1), L6); // Result
+    TFunction_IFunction iFunc6(L6);
+    iFunc6.GetGraphNode()->SetStatus(TFunction_ES_NotExecuted);
+    // 7:
+    TFunction_IFunction::NewFunction(L7, SimpleDriver::GetID());
+    TDataStd_Name::Set(L7, "7");
+    TDataStd_Real::Set(L7, time); // Argument
+    TDF_Reference::Set(L7.FindChild(1).FindChild(1), L4); // Argument F7 -> F4
+    TDF_Reference::Set(L7.FindChild(2).FindChild(1), L7); // Result
+    TFunction_IFunction iFunc7(L7);
+    iFunc7.GetGraphNode()->SetStatus(TFunction_ES_NotExecuted);
+
+    // Construct the dependencies between functions.
+    TFunction_IFunction::UpdateDependencies(mainLabel);
+
+    // Set the functions 1 and 2 modified
+    iFunc1.GetLogbook()->SetTouched(L1);
+    iFunc2.GetLogbook()->SetTouched(L2);
+
+    // Draw the model
+    graph->createModel(doc);
+}
+
+void MainWindow::createDefaultModel2()
+{
+    Handle(AppStd_Application) app = MainWindow::getApplication();
+    Handle(TDocStd_Document) doc;
+    app->NewDocument("BinOcaf", doc);
+    //app->Open("W:\\TestFM\\model2.cbf", doc);
+    TDF_Label mainLabel = doc->Main();
+
+    // Initialize function drivers
+    TFunction_DriverTable::Get()->AddDriver(PointDriver::GetID(), new PointDriver());
+    TFunction_DriverTable::Get()->AddDriver(CircleDriver::GetID(), new CircleDriver());
+    TFunction_DriverTable::Get()->AddDriver(PrismDriver::GetID(), new PrismDriver());
+    TFunction_DriverTable::Get()->AddDriver(ConeDriver::GetID(), new ConeDriver());
+    TFunction_DriverTable::Get()->AddDriver(CylinderDriver::GetID(), new CylinderDriver());
+    TFunction_DriverTable::Get()->AddDriver(ShapeSaverDriver::GetID(), new ShapeSaverDriver());
+
+    // Create a tree of functions
+    TDF_Label Lpoint1  = mainLabel.FindChild(1);
+    TDF_Label Lpoint2  = mainLabel.FindChild(2);
+    TDF_Label Lpoint3  = mainLabel.FindChild(3);
+    TDF_Label Lpoint4  = mainLabel.FindChild(4);
+    TDF_Label Lcircle1 = mainLabel.FindChild(5);
+    TDF_Label Lcircle2 = mainLabel.FindChild(6);
+    TDF_Label Lcircle3 = mainLabel.FindChild(7);
+    TDF_Label Lcircle4 = mainLabel.FindChild(8);
+    TDF_Label Lprism1  = mainLabel.FindChild(9);
+    TDF_Label Lprism2  = mainLabel.FindChild(10);
+    TDF_Label Lprism3  = mainLabel.FindChild(11);
+    TDF_Label Lprism4  = mainLabel.FindChild(12);
+    TDF_Label Lcone1   = mainLabel.FindChild(13);
+    TDF_Label Lcyl1    = mainLabel.FindChild(14);
+    TDF_Label Lcyl2    = mainLabel.FindChild(15);
+    TDF_Label Lcyl3    = mainLabel.FindChild(16);
+    TDF_Label Lcyl4    = mainLabel.FindChild(17);
+    TDF_Label Lcyl5    = mainLabel.FindChild(18);
+    TDF_Label Lcyl6    = mainLabel.FindChild(19);
+    TDF_Label Lcyl7    = mainLabel.FindChild(20);
+    TDF_Label Lcyl8    = mainLabel.FindChild(21);
+    TDF_Label Lcone2   = mainLabel.FindChild(22);
+    TDF_Label Lshape1  = mainLabel.FindChild(23);
+
+    // Set a logbook.
+    Handle(TFunction_Logbook) logbook = TFunction_Logbook::Set(mainLabel);
+
+    // Points:
+    // Point 1:
+    TFunction_IFunction::NewFunction(Lpoint1, PointDriver::GetID());
+    TDataStd_Name::Set(Lpoint1, "P1");
+    Handle(TDataStd_RealArray) arr1 = TDataStd_RealArray::Set(Lpoint1, 1, 3);
+    arr1->SetValue(1, -50);
+    arr1->SetValue(2, -50);
+    arr1->SetValue(3, 0);
+    TDF_Reference::Set(Lpoint1.FindChild(1).FindChild(1), Lpoint1); // Argument
+    TDF_Reference::Set(Lpoint1.FindChild(2).FindChild(1), Lpoint1); // Result
+    TFunction_IFunction iFuncPoint1(Lpoint1);
+    iFuncPoint1.SetStatus(TFunction_ES_NotExecuted);
+    // Point 2:
+    TFunction_IFunction::NewFunction(Lpoint2, PointDriver::GetID());
+    TDataStd_Name::Set(Lpoint2, "P2");
+    Handle(TDataStd_RealArray) arr2 = TDataStd_RealArray::Set(Lpoint2, 1, 3);
+    arr2->SetValue(1, 50);
+    arr2->SetValue(2, -50);
+    arr2->SetValue(3, 0);
+    TDF_Reference::Set(Lpoint2.FindChild(1).FindChild(1), Lpoint2); // Argument
+    TDF_Reference::Set(Lpoint2.FindChild(2).FindChild(1), Lpoint2); // Result
+    TFunction_IFunction iFuncPoint2(Lpoint2);
+    iFuncPoint2.SetStatus(TFunction_ES_NotExecuted);
+    // Point 3:
+    TFunction_IFunction::NewFunction(Lpoint3, PointDriver::GetID());
+    TDataStd_Name::Set(Lpoint3, "P3");
+    Handle(TDataStd_RealArray) arr3 = TDataStd_RealArray::Set(Lpoint3, 1, 3);
+    arr3->SetValue(1, 50);
+    arr3->SetValue(2, 50);
+    arr3->SetValue(3, 0);
+    TDF_Reference::Set(Lpoint3.FindChild(1).FindChild(1), Lpoint3); // Argument
+    TDF_Reference::Set(Lpoint3.FindChild(2).FindChild(1), Lpoint3); // Result
+    TFunction_IFunction iFuncPoint3(Lpoint3);
+    iFuncPoint3.SetStatus(TFunction_ES_NotExecuted);
+    // Point 4:
+    TFunction_IFunction::NewFunction(Lpoint4, PointDriver::GetID());
+    TDataStd_Name::Set(Lpoint4, "P4");
+    Handle(TDataStd_RealArray) arr4 = TDataStd_RealArray::Set(Lpoint4, 1, 3);
+    arr4->SetValue(1, -50);
+    arr4->SetValue(2, 50);
+    arr4->SetValue(3, 0);
+    TDF_Reference::Set(Lpoint4.FindChild(1).FindChild(1), Lpoint4); // Argument
+    TDF_Reference::Set(Lpoint4.FindChild(2).FindChild(1), Lpoint4); // Result
+    TFunction_IFunction iFuncPoint4(Lpoint4);
+    iFuncPoint4.SetStatus(TFunction_ES_NotExecuted);
+    // Circles:
+    // Circle 1:
+    TFunction_IFunction::NewFunction(Lcircle1, CircleDriver::GetID());
+    TDataStd_Name::Set(Lcircle1, "C1");
+    TDataStd_Real::Set(Lcircle1, 10);
+    TDF_Reference::Set(Lcircle1.FindChild(1).FindChild(1), Lpoint1); // Argument: point
+    TDF_Reference::Set(Lcircle1.FindChild(2).FindChild(1), Lcircle1); // Result
+    TFunction_IFunction iFuncCircle1(Lcircle1);
+    iFuncCircle1.SetStatus(TFunction_ES_NotExecuted);
+    // Circle 2:
+    TFunction_IFunction::NewFunction(Lcircle2, CircleDriver::GetID());
+    TDataStd_Name::Set(Lcircle2, "C2");
+    TDataStd_Real::Set(Lcircle2, 20);
+    TDF_Reference::Set(Lcircle2.FindChild(1).FindChild(1), Lpoint2); // Argument: point
+    TDF_Reference::Set(Lcircle2.FindChild(2).FindChild(1), Lcircle2); // Result
+    TFunction_IFunction iFuncCircle2(Lcircle2);
+    iFuncCircle2.SetStatus(TFunction_ES_NotExecuted);
+    // Circle 3:
+    TFunction_IFunction::NewFunction(Lcircle3, CircleDriver::GetID());
+    TDataStd_Name::Set(Lcircle3, "C3");
+    TDataStd_Real::Set(Lcircle3, 30);
+    TDF_Reference::Set(Lcircle3.FindChild(1).FindChild(1), Lpoint3); // Argument: point
+    TDF_Reference::Set(Lcircle3.FindChild(2).FindChild(1), Lcircle3); // Result
+    TFunction_IFunction iFuncCircle3(Lcircle3);
+    iFuncCircle3.SetStatus(TFunction_ES_NotExecuted);
+    // Circle 4:
+    TFunction_IFunction::NewFunction(Lcircle4, CircleDriver::GetID());
+    TDataStd_Name::Set(Lcircle4, "C4");
+    TDataStd_Real::Set(Lcircle4, 40);
+    TDF_Reference::Set(Lcircle4.FindChild(1).FindChild(1), Lpoint4); // Argument: point
+    TDF_Reference::Set(Lcircle4.FindChild(2).FindChild(1), Lcircle4); // Result
+    TFunction_IFunction iFuncCircle4(Lcircle4);
+    iFuncCircle4.SetStatus(TFunction_ES_NotExecuted);
+    // Prisms:
+    // Prism 1:
+    TFunction_IFunction::NewFunction(Lprism1, PrismDriver::GetID());
+    TDataStd_Name::Set(Lprism1, "Pr1");
+    TDataStd_Real::Set(Lprism1, 30);
+    TDF_Reference::Set(Lprism1.FindChild(1).FindChild(1), Lcircle1); // Argument: point
+    TDF_Reference::Set(Lprism1.FindChild(2).FindChild(1), Lprism1); // Result
+    TDF_Reference::Set(Lprism1.FindChild(2).FindChild(2), Lprism1.FindChild(3)); // Result (top)
+    TFunction_IFunction iFuncPrism1(Lprism1);
+    iFuncPrism1.SetStatus(TFunction_ES_NotExecuted);
+    // Prism 2:
+    TFunction_IFunction::NewFunction(Lprism2, PrismDriver::GetID());
+    TDataStd_Name::Set(Lprism2, "Pr2");
+    TDataStd_Real::Set(Lprism2, 30);
+    TDF_Reference::Set(Lprism2.FindChild(1).FindChild(1), Lcircle2); // Argument: point
+    TDF_Reference::Set(Lprism2.FindChild(2).FindChild(1), Lprism2); // Result
+    TDF_Reference::Set(Lprism2.FindChild(2).FindChild(2), Lprism2.FindChild(3)); // Result (top)
+    TFunction_IFunction iFuncPrism2(Lprism2);
+    iFuncPrism2.SetStatus(TFunction_ES_NotExecuted);
+    // Prism 3:
+    TFunction_IFunction::NewFunction(Lprism3, PrismDriver::GetID());
+    TDataStd_Name::Set(Lprism3, "Pr3");
+    TDataStd_Real::Set(Lprism3, 30);
+    TDF_Reference::Set(Lprism3.FindChild(1).FindChild(1), Lcircle3); // Argument: point
+    TDF_Reference::Set(Lprism3.FindChild(2).FindChild(1), Lprism3); // Result
+    TDF_Reference::Set(Lprism3.FindChild(2).FindChild(2), Lprism3.FindChild(3)); // Result (top)
+    TFunction_IFunction iFuncPrism3(Lprism3);
+    iFuncPrism3.SetStatus(TFunction_ES_NotExecuted);
+    // Prism 4:
+    TFunction_IFunction::NewFunction(Lprism4, PrismDriver::GetID());
+    TDataStd_Name::Set(Lprism4, "Pr4");
+    TDataStd_Real::Set(Lprism4, 30);
+    TDF_Reference::Set(Lprism4.FindChild(1).FindChild(1), Lcircle4); // Argument: point
+    TDF_Reference::Set(Lprism4.FindChild(2).FindChild(1), Lprism4); // Result
+    TDF_Reference::Set(Lprism4.FindChild(2).FindChild(2), Lprism4.FindChild(3)); // Result (top)
+    TFunction_IFunction iFuncPrism4(Lprism4);
+    iFuncPrism4.SetStatus(TFunction_ES_NotExecuted);
+    // Cone 1:
+    TFunction_IFunction::NewFunction(Lcone1, ConeDriver::GetID());
+    TDataStd_Name::Set(Lcone1, "Co1");
+    TDataStd_Real::Set(Lcone1, 20);
+    TDF_Reference::Set(Lcone1.FindChild(1).FindChild(1), Lprism1.FindChild(3)); // Argument: top
+    TDF_Reference::Set(Lcone1.FindChild(1).FindChild(2), Lprism2.FindChild(3)); // Argument: top
+    TDF_Reference::Set(Lcone1.FindChild(1).FindChild(3), Lprism3.FindChild(3)); // Argument: top
+    TDF_Reference::Set(Lcone1.FindChild(1).FindChild(4), Lprism4.FindChild(3)); // Argument: top
+    TDF_Reference::Set(Lcone1.FindChild(2).FindChild(1), Lcone1); // Result
+    TDF_Reference::Set(Lcone1.FindChild(2).FindChild(2), Lcone1.FindChild(3)); // Result
+    TFunction_IFunction iFuncCone1(Lcone1);
+    iFuncCone1.SetStatus(TFunction_ES_NotExecuted);
+    // Cylinders:
+    // Cylinder 1:
+    TFunction_IFunction::NewFunction(Lcyl1, CylinderDriver::GetID());
+    TDataStd_Name::Set(Lcyl1, "Cyl1");
+    Handle(TDataStd_RealArray) carr1 = TDataStd_RealArray::Set(Lcyl1, 1, 3);
+    carr1->SetValue(1, 10.0);
+    carr1->SetValue(2, 45.0);
+    carr1->SetValue(3, 20.0);
+    TDF_Reference::Set(Lcyl1.FindChild(1).FindChild(1), Lcone1.FindChild(3)); // Argument: top
+    TDF_Reference::Set(Lcyl1.FindChild(2).FindChild(1), Lcyl1); // Result
+    TDF_Reference::Set(Lcyl1.FindChild(2).FindChild(2), Lcyl1.FindChild(3)); // Result
+    TFunction_IFunction iFuncCyl1(Lcyl1);
+    iFuncCyl1.SetStatus(TFunction_ES_NotExecuted);
+    // Cylinder 2:
+    TFunction_IFunction::NewFunction(Lcyl2, CylinderDriver::GetID());
+    TDataStd_Name::Set(Lcyl2, "Cyl2");
+    Handle(TDataStd_RealArray) carr2 = TDataStd_RealArray::Set(Lcyl2, 1, 3);
+    carr2->SetValue(1, 10.0);
+    carr2->SetValue(2, 90.0);
+    carr2->SetValue(3, 20.0);
+    TDF_Reference::Set(Lcyl2.FindChild(1).FindChild(1), Lcone1.FindChild(3)); // Argument: top
+    TDF_Reference::Set(Lcyl2.FindChild(2).FindChild(1), Lcyl2); // Result
+    TDF_Reference::Set(Lcyl2.FindChild(2).FindChild(2), Lcyl2.FindChild(3)); // Result
+    TFunction_IFunction iFuncCyl2(Lcyl2);
+    iFuncCyl2.SetStatus(TFunction_ES_NotExecuted);
+    // Cylinder 3:
+    TFunction_IFunction::NewFunction(Lcyl3, CylinderDriver::GetID());
+    TDataStd_Name::Set(Lcyl3, "Cyl3");
+    Handle(TDataStd_RealArray) carr3 = TDataStd_RealArray::Set(Lcyl3, 1, 3);
+    carr3->SetValue(1, 10.0);
+    carr3->SetValue(2, 135.0);
+    carr3->SetValue(3, 20.0);
+    TDF_Reference::Set(Lcyl3.FindChild(1).FindChild(1), Lcone1.FindChild(3)); // Argument: top
+    TDF_Reference::Set(Lcyl3.FindChild(2).FindChild(1), Lcyl3); // Result
+    TDF_Reference::Set(Lcyl3.FindChild(2).FindChild(2), Lcyl3.FindChild(3)); // Result
+    TFunction_IFunction iFuncCyl3(Lcyl3);
+    iFuncCyl3.SetStatus(TFunction_ES_NotExecuted);
+    // Cylinder 4:
+    TFunction_IFunction::NewFunction(Lcyl4, CylinderDriver::GetID());
+    TDataStd_Name::Set(Lcyl4, "Cyl4");
+    Handle(TDataStd_RealArray) carr4 = TDataStd_RealArray::Set(Lcyl4, 1, 3);
+    carr4->SetValue(1, 10.0);
+    carr4->SetValue(2, 180.0);
+    carr4->SetValue(3, 20.0);
+    TDF_Reference::Set(Lcyl4.FindChild(1).FindChild(1), Lcone1.FindChild(3)); // Argument: top
+    TDF_Reference::Set(Lcyl4.FindChild(2).FindChild(1), Lcyl4); // Result
+    TDF_Reference::Set(Lcyl4.FindChild(2).FindChild(2), Lcyl4.FindChild(3)); // Result
+    TFunction_IFunction iFuncCyl4(Lcyl4);
+    iFuncCyl4.SetStatus(TFunction_ES_NotExecuted);
+    // Cylinder 5:
+    TFunction_IFunction::NewFunction(Lcyl5, CylinderDriver::GetID());
+    TDataStd_Name::Set(Lcyl5, "Cyl5");
+    Handle(TDataStd_RealArray) carr5 = TDataStd_RealArray::Set(Lcyl5, 1, 3);
+    carr5->SetValue(1, 10.0);
+    carr5->SetValue(2, 225.0);
+    carr5->SetValue(3, 20.0);
+    TDF_Reference::Set(Lcyl5.FindChild(1).FindChild(1), Lcone1.FindChild(3)); // Argument: top
+    TDF_Reference::Set(Lcyl5.FindChild(2).FindChild(1), Lcyl5); // Result
+    TDF_Reference::Set(Lcyl5.FindChild(2).FindChild(2), Lcyl5.FindChild(3)); // Result
+    TFunction_IFunction iFuncCyl5(Lcyl5);
+    iFuncCyl5.SetStatus(TFunction_ES_NotExecuted);
+    // Cylinder 6:
+    TFunction_IFunction::NewFunction(Lcyl6, CylinderDriver::GetID());
+    TDataStd_Name::Set(Lcyl6, "Cyl6");
+    Handle(TDataStd_RealArray) carr6 = TDataStd_RealArray::Set(Lcyl6, 1, 3);
+    carr6->SetValue(1, 10.0);
+    carr6->SetValue(2, 270.0);
+    carr6->SetValue(3, 20.0);
+    TDF_Reference::Set(Lcyl6.FindChild(1).FindChild(1), Lcone1.FindChild(3)); // Argument: top
+    TDF_Reference::Set(Lcyl6.FindChild(2).FindChild(1), Lcyl6); // Result
+    TDF_Reference::Set(Lcyl6.FindChild(2).FindChild(2), Lcyl6.FindChild(3)); // Result
+    TFunction_IFunction iFuncCyl6(Lcyl6);
+    iFuncCyl6.SetStatus(TFunction_ES_NotExecuted);
+    // Cylinder 7:
+    TFunction_IFunction::NewFunction(Lcyl7, CylinderDriver::GetID());
+    TDataStd_Name::Set(Lcyl7, "Cyl7");
+    Handle(TDataStd_RealArray) carr7 = TDataStd_RealArray::Set(Lcyl7, 1, 3);
+    carr7->SetValue(1, 10.0);
+    carr7->SetValue(2, 315.0);
+    carr7->SetValue(3, 20.0);
+    TDF_Reference::Set(Lcyl7.FindChild(1).FindChild(1), Lcone1.FindChild(3)); // Argument: top
+    TDF_Reference::Set(Lcyl7.FindChild(2).FindChild(1), Lcyl7); // Result
+    TDF_Reference::Set(Lcyl7.FindChild(2).FindChild(2), Lcyl7.FindChild(3)); // Result
+    TFunction_IFunction iFuncCyl7(Lcyl7);
+    iFuncCyl7.SetStatus(TFunction_ES_NotExecuted);
+    // Cylinder 8:
+    TFunction_IFunction::NewFunction(Lcyl8, CylinderDriver::GetID());
+    TDataStd_Name::Set(Lcyl8, "Cyl8");
+    Handle(TDataStd_RealArray) carr8 = TDataStd_RealArray::Set(Lcyl8, 1, 3);
+    carr8->SetValue(1, 10.0);
+    carr8->SetValue(2, 0.0);
+    carr8->SetValue(3, 20.0);
+    TDF_Reference::Set(Lcyl8.FindChild(1).FindChild(1), Lcone1.FindChild(3)); // Argument: top
+    TDF_Reference::Set(Lcyl8.FindChild(2).FindChild(1), Lcyl8); // Result
+    TDF_Reference::Set(Lcyl8.FindChild(2).FindChild(2), Lcyl8.FindChild(3)); // Result
+    TFunction_IFunction iFuncCyl8(Lcyl8);
+    iFuncCyl8.SetStatus(TFunction_ES_NotExecuted);
+    // Cone 2:
+    TFunction_IFunction::NewFunction(Lcone2, ConeDriver::GetID());
+    TDataStd_Name::Set(Lcone2, "Co2");
+    TDataStd_Real::Set(Lcone2, 30);
+    TDF_Reference::Set(Lcone2.FindChild(1).FindChild(1), Lcyl1.FindChild(3)); // Argument: top
+    TDF_Reference::Set(Lcone2.FindChild(1).FindChild(2), Lcyl3.FindChild(3)); // Argument: top
+    TDF_Reference::Set(Lcone2.FindChild(1).FindChild(3), Lcyl5.FindChild(3)); // Argument: top
+    TDF_Reference::Set(Lcone2.FindChild(1).FindChild(4), Lcyl7.FindChild(3)); // Argument: top
+    TDF_Reference::Set(Lcone2.FindChild(2).FindChild(1), Lcone2); // Result
+    TDF_Reference::Set(Lcone2.FindChild(2).FindChild(2), Lcone2.FindChild(3)); // Result
+    TFunction_IFunction iFuncCone2(Lcone2);
+    iFuncCone2.SetStatus(TFunction_ES_NotExecuted);
+    // Shape saver 1:
+    TFunction_IFunction::NewFunction(Lshape1, ShapeSaverDriver::GetID());
+    TDataStd_Name::Set(Lshape1, "Sh");
+    TFunction_IFunction iFuncShape1(Lshape1);
+    iFuncShape1.SetStatus(TFunction_ES_NotExecuted);
+    // Arguments of this functions - results of all functions
+    int iTag = 1;
+    const TFunction_DoubleMapOfIntegerLabel& all = iFuncShape1.GetAllFunctions();
+    TFunction_DoubleMapIteratorOfDoubleMapOfIntegerLabel itrm(all);
+    for (; itrm.More(); itrm.Next())
+    {
+        TFunction_IFunction iFunc(itrm.Key2());
+        TDF_LabelList res;
+        iFunc.Results(res);
+        TDF_ListIteratorOfLabelList itrl(res);
+        for (; itrl.More(); itrl.Next(), iTag++)
+        {
+            TDF_Reference::Set(Lshape1.FindChild(1).FindChild(iTag), itrl.Value());
+        }
+    }
+
+    // Construct the dependencies between functions.
+    TFunction_IFunction::UpdateDependencies(mainLabel);
+
+    // Set the functions 1 .. 4 modified
+    TFunction_IFunction(mainLabel).GetLogbook()->SetTouched(Lpoint1);
+    TFunction_IFunction(mainLabel).GetLogbook()->SetTouched(Lpoint2);
+    TFunction_IFunction(mainLabel).GetLogbook()->SetTouched(Lpoint3);
+    TFunction_IFunction(mainLabel).GetLogbook()->SetTouched(Lpoint4);
+
+    // Draw the model
+    graph->createModel(doc);
+
+    //app->SaveAs(doc, "W:\\TestFM\\model2.cbf");
+}
\ No newline at end of file
diff --git a/samples/qt/FuncDemo/src/mainwindow.h b/samples/qt/FuncDemo/src/mainwindow.h
new file mode 100644 (file)
index 0000000..5c9d1c0
--- /dev/null
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2004-2007 Trolltech ASA. All rights reserved.
+**
+** This file is part of the example classes of the Qt Toolkit.
+**
+** Licensees holding a valid Qt License Agreement may use this file in
+** accordance with the rights, responsibilities and obligations
+** contained therein.  Please consult your licensing agreement or
+** contact sales@trolltech.com if any conditions of this licensing
+** agreement are not clear to you.
+**
+** Further information about Qt licensing is available at:
+** http://www.trolltech.com/products/qt/licensing.html or by
+** contacting info@trolltech.com.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+#include <AppStd_Application.hxx>
+
+class QAction;
+class QMenu;
+class GraphWidget;
+
+static Handle(AppStd_Application) gApplication;
+
+class MainWindow : public QMainWindow
+{
+    Q_OBJECT
+
+public:
+    MainWindow();
+
+    static Handle(AppStd_Application) getApplication();
+
+protected:
+    void closeEvent(QCloseEvent *event);
+
+private slots:
+    void model1();
+    void model2();
+    void compute();
+    void nbThreads();
+    void about();
+
+private:
+    void createActions();
+    void createMenus();
+    void createToolBars();
+    void createStatusBar();
+
+    GraphWidget* graph;
+
+    QMenu *computeMenu;
+    QMenu *helpMenu;
+    QToolBar *computeToolBar;
+    QAction *model1Act;
+    QAction *model2Act;
+    QAction *computeAct;
+    QAction *nbThreadsAct;
+    QAction *exitAct;
+    QAction *aboutAct;
+
+    // Default models.
+    // The Model 1 consists of a set of simple functions
+    // of the same type.
+    // These functions have a double parameter: relative time of execution, and
+    // a "forced" parameter: another function.
+    // Actually, the functions are independent, 
+    // but we "force" a dependency between them to test the Function Mechanism using simple functions.
+    // So, a function uses a double parameter and produces nothing.
+    // I use a TDF_Reference to refer from a function to another function.
+    // This way I define a dependency.
+    void createDefaultModel1();
+
+    // Another default model, topological.
+    void createDefaultModel2();
+
+    // Redraw the nodes (change their colour).            
+    void redrawGraph();
+};
+
+#endif
diff --git a/samples/qt/FuncDemo/src/node.cpp b/samples/qt/FuncDemo/src/node.cpp
new file mode 100644 (file)
index 0000000..ec0d07d
--- /dev/null
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2006-2007 Trolltech ASA. All rights reserved.
+**
+** This file is part of the example classes of the Qt Toolkit.
+**
+** Licensees holding a valid Qt License Agreement may use this file in
+** accordance with the rights, responsibilities and obligations
+** contained therein.  Please consult your licensing agreement or
+** contact sales@trolltech.com if any conditions of this licensing
+** agreement are not clear to you.
+**
+** Further information about Qt licensing is available at:
+** http://www.trolltech.com/products/qt/licensing.html or by
+** contacting info@trolltech.com.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#include <QGraphicsScene>
+#include <QGraphicsSceneMouseEvent>
+#include <QPainter>
+#include <QStyleOption>
+
+#include "edge.h"
+#include "node.h"
+#include "graphwidget.h"
+
+#include <TFunction_IFunction.hxx>
+#include <TFunction_GraphNode.hxx>
+#include <TDataStd_Name.hxx>
+#include <TDataStd_Tick.hxx>
+
+Node::Node(GraphWidget *graphWidget)
+    : graph(graphWidget)
+{
+    setFlag(ItemIsMovable);
+    setZValue(1);
+}
+
+void Node::setFunction(const TDF_Label& func)
+{
+    myFunction = func;
+}
+
+const TDF_Label& Node::getFunction() const
+{
+    return myFunction;
+}
+
+void Node::addEdge(Edge *edge)
+{
+    edgeList << edge;
+    edge->adjust();
+}
+
+QList<Edge *> Node::edges() const
+{
+    return edgeList;
+}
+
+QRectF Node::boundingRect() const
+{
+    qreal adjust = 2;
+    return QRectF(-15 - adjust, -15 - adjust,
+                  33 + adjust, 33 + adjust);
+}
+
+QPainterPath Node::shape() const
+{
+    QPainterPath path;
+    path.addEllipse(-15, -15, 30, 30);
+    return path;
+}
+
+void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
+{
+    painter->setPen(Qt::NoPen);
+    painter->setBrush(Qt::darkGray);
+    painter->drawEllipse(-12, -12, 30, 30);
+
+    QColor light_color(Qt::yellow);
+    TFunction_IFunction iFunc(myFunction);
+    Handle(TFunction_GraphNode) graphNode = iFunc.GetGraphNode();
+    TFunction_ExecutionStatus status = graphNode->GetStatus();
+    switch (status)
+    {
+    case TFunction_ES_WrongDefinition:
+    case TFunction_ES_Failed:
+        light_color = Qt::red;
+        break;
+    case TFunction_ES_NotExecuted:
+        light_color = Qt::green;
+        break;
+    case TFunction_ES_Executing:
+        light_color = Qt::yellow;
+        break;
+    case TFunction_ES_Succeeded:
+        light_color = Qt::blue;
+        break;
+    }
+    if (myFunction.IsAttribute(TDataStd_Tick::GetID()))
+        light_color = Qt::white;
+    QColor dark_color = light_color.dark(150);
+
+    QRadialGradient gradient(-3, -3, 10);
+    if (option->state & QStyle::State_Sunken) {
+        gradient.setCenter(3, 3);
+        gradient.setFocalPoint(3, 3);
+        gradient.setColorAt(1, light_color.light(120));
+        gradient.setColorAt(0, dark_color.light(120));
+    } else {
+        gradient.setColorAt(0, light_color);
+        gradient.setColorAt(1, dark_color);
+    }
+    painter->setBrush(gradient);
+    painter->setPen(QPen(Qt::black, 0));
+    painter->drawEllipse(-15, -15, 30, 30);
+    
+    QString s;
+    Handle(TDataStd_Name) n;
+    if (myFunction.FindAttribute(TDataStd_Name::GetID(), n))
+        s = TCollection_AsciiString(n->Get()).ToCString();
+    painter->drawText(-7, 3, s);
+}
+
+QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value)
+{
+    switch (change) {
+    case ItemPositionChange:
+        foreach (Edge *edge, edgeList)
+            edge->adjust();
+        break;
+    default:
+        break;
+    };
+
+    return QGraphicsItem::itemChange(change, value);
+}
+
+void Node::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+    update();
+    QGraphicsItem::mousePressEvent(event);
+}
+
+void Node::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+    update();
+    QGraphicsItem::mouseReleaseEvent(event);
+}
diff --git a/samples/qt/FuncDemo/src/node.h b/samples/qt/FuncDemo/src/node.h
new file mode 100644 (file)
index 0000000..407aa17
--- /dev/null
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2006-2007 Trolltech ASA. All rights reserved.
+**
+** This file is part of the example classes of the Qt Toolkit.
+**
+** Licensees holding a valid Qt License Agreement may use this file in
+** accordance with the rights, responsibilities and obligations
+** contained therein.  Please consult your licensing agreement or
+** contact sales@trolltech.com if any conditions of this licensing
+** agreement are not clear to you.
+**
+** Further information about Qt licensing is available at:
+** http://www.trolltech.com/products/qt/licensing.html or by
+** contacting info@trolltech.com.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#ifndef NODE_H
+#define NODE_H
+
+#include <QGraphicsItem>
+#include <QList>
+
+#include <TDF_Label.hxx>
+
+class Edge;
+class GraphWidget;
+class QGraphicsSceneMouseEvent;
+
+class Node : public QGraphicsItem
+{
+public:
+    Node(GraphWidget *graphWidget);
+
+    void setFunction(const TDF_Label& func);
+    const TDF_Label& getFunction() const;
+
+    void addEdge(Edge *edge);
+    QList<Edge *> edges() const;
+
+    enum { Type = UserType + 1 };
+    int type() const { return Type; }
+
+    QRectF boundingRect() const;
+    QPainterPath shape() const;
+    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+protected:
+    QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+    void mousePressEvent(QGraphicsSceneMouseEvent *event);
+    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+    
+private:
+    QList<Edge *> edgeList;
+    QPointF newPos;
+    GraphWidget *graph;
+    TDF_Label myFunction;
+};
+
+#endif