HOME |
G-System . CAD
Computer-Aided Design
Software
__________________________________________________________________________
C# / WPF / WPF3D / DirectX
Visual Studio 2010
Express / .NET / Windows 7
__________________________________________________________________________
Progress Note / Screen Shots
C# Note WPF Note WPF3D Note
.NET Note
The WPF/C# conversion effort
of the current G-System (VC++/MFC/OpenGL) has officially begun on March 10,
2011.
Below is my working document for this endeavor.
WPF CAD
SYSTEM - NEW
SCREEN SHOT |


2011-June-27
* Porting CFD grid
generation commands into this C#/WPF project.
* Took some time to straighten out arrays and pointers in C++ for this
grid generation algorithm.

The G-System is a desktop CAD software written in roughly 50K lines of
C++ code.
It is based on MFC (Microsoft Foundation Class)
utilizing MDI (Multiple Document Interface) architecture.
Graphics rendering is done by OpenGL.
The current version is based on Visual Studio 2008
(VC++) on Windows 7.
Now, I am going to port the system into C# / WPF / DirectX on .Net
platform.
The IDE is Visual Studio 2010 Express (free) using WPF/C#
on Windows 7.
OLD SYSTEM::
VC++ / MFC / OpenGL
(~50K lines of C++
code)
NEW SYSTEM::
C# / WPF / WPF 3D (DirectX)
Roughly speaking, GUI changes from MFC to WPF. Rendering changes from
OpenGL to WPF 3D (or DirectX).
The rest, after C# porting is done, should work like a
charm - maybe.
ISSUES / CONSIDERATION
2011-March-05 |
Document/View
Architecture : Doc class
/ View class
MFC Document/View
architecture paradigm must be handled by WPF paradigm.
View (viewport)
creation & management :
Create - Resize/Move - Delete
CView + MdiChild:
OnInitialUpdate (MFC), ...
Event-handling /
routing mechanism :
L-button / R-button / Mouse Move / Keyin
Menu event, Mouse event,
Keyboard event, .... Event handling by WPF
Real-time view
rotation : O
Selection - Hit Test
: O
Project (DLL)
Dependency : O
FM Programming
Paradigm : O
Permanent/Temporary
FM : O
Prompt message :
O
OnDraw :
Invalidate()
Draw on all viewports
: O
Persistent Data :
m_elemList <>
Desktop design :
Menu creation, Toolbar creation, Icons,.....
MDI windows :
WPF MdiChild windows
Graphics Rendering :
WPF 3D - GenerateVertices/CreateGLcalls
OpenGL calls must be converted to WPF 3D/DirectX calls
OpenGL display list :
O
Current Plane :
O
CDialog boxes :
Replaced by WPF user controls
VS Project Structure
/ Old VC++ System::
VC++ / MFC /
OpenGL
2011-March-10 |
Solution "GS" / 12 projects --- Visual Studio 2008
Professional / VC++ (~50K lines of VC++/MFC code)
GDoc (2100) / GDoc_1
GFK_viewing (1980)
GFK_linking
(300)
GFK_base_doc
GElemLink (500)
GElemLight (400)
DialogBoxes..... (xxxx)
GView - graphic (4700)
GView2 - text info
GView3 - text info
GData - (2000) --- goes to Doc?
GElement - base class (1100)
GElem1 - general elements (1900 + 560)
GElemCfd - cfd (5300)
GElemPipe - piping (2800) --- delete
GFK_base (750)
GFK_element - creation (3600)
GFK_editing - edit (4500)
Dialogs...
GFK_cfd - meshing (5000)
GFK_piping (3000) --- delete
GUtil - math utility (1800)
VS Project
Structure / New C# System:: C# / WPF / WPF 3D / DirectX 2011-June-10 |
Solution
"G-CS" / 9 projects --- Visual Studio 2010 Express / C# / WPF
GProject_Main
/ exe
(WPF Application)
Control
ns_Main
........ *ns_ for name space
TutorialControl1.xaml / cs
TutorialControl2.xaml / cs
TutorialControl3.xaml / cs
- - - - -
GView.xaml / cs
ns_Main
class CView
......... Keep
this here for now
MainWindow.xaml /
cs
class MainWindow
ns_Main
GDoc.cs ns_Main
class CDoc
GFM_viewing.cs
ns_Main
class CFM_viewing
GFM_linking.cs
ns_Main
class CFM_linking
GFM_base_doc.cs
ns_Main
class CFM_base_doc
GElemLink.cs
ns_Main
class CElemLink
GElemLight.cs
ns_Main
class CElemLight
GProject_View
/ dll
(WPF User Control)
Control
GView.xaml / cs
class CView.....
Kept in GProject_Main for
now
GView2.xaml / cs
class CView2
GProject_Dialog
/ dll
(WPF User control)
Control
GDialog1.xaml / cs
GDialog2.xaml / cs
- - - - -
GProject_FM_command
/ dll
(Class Library)
GFM_base.cs
ns_FM_command
class CFM_base
GFM_element.cs
GFM_editing.cs
GFM_cfd.cs
GProject_Data
/ dll
(Class Library)
GData.cs
ns_Data
class CData
GProject_Element
/ dll
(Class Library)
GElement.cs
ns_Element
class
CElemBase, CElemBase1D/2D/3D, ...Elbow3D..
GProject_Utility
/ dll
(Class Library)
GUtility.cs
ns_Utility
class
CPoint2D, CPoint3D, CViewMatrix, ...
GProject_Global / dll
(Class Library)
GGlobal.cs
ns_Global
class
G
WPF.MDI
/ dll
MdiChild.cs
WPF.MDI
MdiContainer.cs
WPF.MDI
------------------------------------------------
future consideration
GProject_DB2 / exe
GMySQL.cs
ns_DB2
GProject_Controller
/ exe
GController.cs
ns_Controller
MENU STRUCTURE OF G-C# SYSTEM
2011-June-03 |
File |
Edit |
View |
Geometry |
CFD Mesh |
Current
Plane |
Light |
Tools |
Window |
Help |
|
New
Open
Close
-----
Save
Save As...
-----
Document Name...
-----
Exit
|
Undo
Redo
-----
Cut
Copy
Paste
-----
FM Delete
FM Hide
Show All
-----
FM Translate
FM Rotate
FM Scale
FM Mirror
FM Jump
-----
Copy Mode
-----
FM Modify
-----
Color
Line Width
Material
Layer
-----
FM Group
-----
FM Change Color
FM Change Layer
-----
FM Copy Window
FM Paste Window
|
Perspective Projection
-----
Display
Shaded
Wireframe
Clipping Planes
Near Plane
Far Plane
-----
Preset Views
Ortho XY
Ortho XZ
Ortho YZ
Iso X
Iso Y
Iso Z
View Setting
Snap to Current Plane
Define by 3 Points
Pan Mode
Same Camera Orientation
Turn Camera Head
Rotate
Rotate XYZ Axis
Rotate Screen
Rotate Arbitrary Axis
Lens Angle
Zoom
By Lens Angle
By Camera Move
Zoom Box
Fit All
-----
Toolbar
-----
Properties...
|
FM
Point
FM Line
FM Rectangle
FM Circle
FM Box / Pyramid
FM Cylinder / Cone
FM Elbow
-----
FM Revolve
FM Extrude
FM Sweep / Transverse
FM Transit
-----
FM Text
|
FM
Domain
FM Multi-Box Domain
FM Multi-Cylinder Domain
-----
FM Line Edge
FM Arc Edge
-----
Structure Domain
-----
FM Slice
FM Insert
-----
FM Grid Generation
-----
Output Domain File
Output Grid File
|
Preset Planes
XY Plane
XZ Plane
YZ Plane
Plane Setting
Move Origin
Set Normal
On Element
Define by 3 Points
Rotate
-----
Grid Snap
-----
Properties...
|
New
Light
Move Light
Delete Light
Named Light
-----
Properties...
|
Coordinate Key-in Mode
Rectangular
Cylindrical
Spherical
-----
Global
Current Plane
-----
Absolute
Relative
-----
FM
Analysis
-----
Setting
Customize...
Options...
|
New Viewport
-----
Tile
Cascade
-----
2-Viewport Layout
3-Viewport Layout
4-Viewport Layout
-----
Window Theme
Aero
Luna
Generic
|
Help
User Guide
Documentation
-----
About G-System
-----
Tutorial Examples...
|
|
Critical
Data Flow and Organization
2011-March-22 |
-----------------------------------------------------------------------------------------
MainWindow.xaml.cs
- Main WPF application
window
<Member data>
public CDoc pDoc;
<Constructor>
pDoc = new CDoc (this);
<View creation - Menu: New Window>
private void
miNewWindow_Click (object sender, RoutedEventArgs e)
{
CView pV = new CView (pDoc, pDoc.m_pData);
pDoc.m_viewList.Add (pV);
MdiChild mdiView = new MdiChild()
{
Title = "WPF 3D - CView",
Content = pV,
Width = 400, Height = 400,
};
Canvas.SetLeft (mdiView, 400);
Canvas.SetTop (mdiView, 250);
Container.Children.Add (mdiView);
// (1) Save in container
pDoc.m_mdiViewList.Add (mdiView);
// (2) Save in view
list
m_mdiViewList.Add (mdiView;
m_viewList.Add (pV);
this.cameraControl2 = pV;
}
<FM command initiation>
private void
miFMPoint_Click(object sender, RoutedEventArgs e)
{
// FM Point...
}
-----------------------------------------------------------------------------------------
GDoc.cs
- Document class
<Member data>
public CData m_pData;
public CView m_pVptCur = new CView();
// viewport currency
public List<MdiChild>
m_mdiViewList = new List<MdiChild>();
public List<CView>
m_viewList = new List<CView>();
// not needed?
public CFM_base m_pFM;
public CFM_base m_pFMT;
public CView
m_pViewEvent = new CView();
// view of event-origin
<Constructor>
public CDoc (Window window)
{
this.window = window;
m_pData = new CData();
// Create default view -- cannot ??
// vw.Owner = this;
// window.Show();
}
<FM command - default FM is Point creation>
m_pFM = m_pFKM = null; // This will be deleted unless null
m_pFM = new
CFM_createPoint (m_pData);
-----------------------------------------------------------------------------------------
CView.xaml.cs
- View class
<Member data>
public CData m_pData;
public CDoc m_pDoc;
<Constructor>
InitializeComponent();
// WPF
this.m_pDoc = pDoc;
this.m_pData =
pData;
InitialViewDefault();
<Event generation>
private void
UserControl_PreviewMouseLeftButtonDown (object sender,
MouseButtonEventArgs e)
{
// This is where an
event is issued to the active FM command
CFM_base m_pFM = m_pDoc.GetActiveFK();
m_pFM.EventForSEL(1, null);
m_pFM.EventForDEFPT(1, null);
m_pFM.EventForIND(1, null);
m_pFM.EventForKY1(1, null);
m_pFM.EventForKY2(1, null);
m_pFM.EventForKY3(1, null);
m_pFM.EventForLBD(1, null);
m_pFM.EventForLBU(1, null);
m_pFM.EventForLB2(1, null);
}
private void
UserControl_PreviewMouseRightButtonDown (object sender,
MouseButtonEventArgs e)
{
// Real-time view
manipulation.... no event issued to FM commands
this.myCamera.Position
= new Point3D(cameraPosX, cameraPosY, cameraPosZ);
}
-----------------------------------------------------------------------------------------
CData.cs
- Data class - primary
repository of Doc's data
<Member data>
public List<object>
m_elemList = new List<object>();
public List<object>
m_lightList = new List<object>();
public List<object>
m_viewMatrixList = new List<object>();
// View Matrix
public List<object>
m_curPlaneList = new List<object>();
// Current Planes
-----------------------------------------------------------------------------------------
CFM_Command.cs
- FM commands...
<Member data>
public CDoc pDoc;xxxxxxxxxxx
<Constructor>
pDoc = new CDoc (this);xxxxxxxxxxxxxxxx
<View creation - Menu: New Window>
private void
miNewWindow_Click (objectxxxxxxxxxxxxxxx sender, RoutedEventArgs e)
{
CView pV = new CView (pDoc, pDoc.m_pData);xxxxxxxxxxxxxxxxx
pDoc.m_viewList.Add (pV);
How to add
a New Project to my G_CS Solution 2011-March-12 |
How to add a new project - Class Library (GUtility)
- Visual Studio 2010 /
Visual C# Express
1. R-click Add >
New Project > Class Library, Name GUtility
2. Replace a newly provided xxx.cs with your own
GUtility.cs code. Add namespace GUtility.
3. R-click References folder of Main project.
Click Add References. Select Project tab. Select GUtility project and
OK.
4. Use "using GUtility" in Main.cs.
How to add a new project - WPF project (GView)
- Visual Studio 2010 /
Visual C# Express
1. R-click Add >
New Project > WPF Application, Name GProjectView
2. Remove App.xaml & MainWindow.xaml - we don't
need them.
3. Add "Controls" folder under this project.
4. R-click the project and select Properties.
Application Tab-->Output
type: Class library.
This will set this
project as DLL (Choosing Window Application will set it as EXE).
How to add a UserControl in Controls folder of a project
- Visual Studio 2010 /
Visual C# Express
1. R-click the
Controls folder of a project. Add > User Control... Select
UserControl (WPF). Enter name GView
2. Replace a newly provided xaml.cs with your own
GView.cs code. Add namespace GView.
How to add references to a project - in order to use "using xxx"
- Visual Studio 2010 /
Visual C# Express
1. R-click
References folder of the Project and click Add Reference... In the
Project tab, select all projects this project is dependent on OK.
Note on "cyclic" dependency of Projects
- Visual Studio 2010 /
Visual C# Express
1. You must not
create a cyclic dependency on other projects when "adding references" on
Reference folder of the project.
2. If two entities (files) depend on each other
(cyclically), they must be placed in the same namespace (project).
How to
Integrate 3DTools to theSolution 2012-Jan-06 |
1.
In VS2010 Solution
Explorer, R-click
3DTools(unavailable),
and removed it from the
solution first.
2. In Windows
Explorer, copy
3DTools folder (that
contains
3DTools.csproj)
to the same
folder that contains
my.solution file as
well as all the
Project folders.
3. In VS2010
Solution Explorer,
R-click Solution and
Add--> Existing
Project... Select
3DTools.csproj that
was copied above.
4. Then for
all Projects that
need this 3DTools,
R-click and Add
Reference... and
select 3DTools & OK.
C# GElement
Hierarchy 2011-March-15 |
-----------------------------------------------------------------------------------------
abstract class CELemBase
{
public abstract CElemBase Clone();
public abstract void GenerateVertices();
public abstract int CreateGLcalls();
public virtual CPoint3D GetMxOrigin();
public virtual CPoint3D GetMxAxisX();
public virtual CPoint3D oid GetMxAxisY();
public virtual CPoint3D GetMxAxisZ();
public virtual void SetMatrix(CViewMatrix
mx) { }
public virtual CViewMatrix GetMatrix() {
return new CViewMatrix(); }
public virtual void SetMxOrigin(double x,
double y, double z) { }
public virtual void SetMxAxisX(double x,
double y, double z) { }
public virtual void SetMxAxisY(double x,
double y, double z) { }
public virtual void SetMxAxisZ(double x,
double y, double z) { }
public virtual void Translate();
public virtual void Rotate();
public virtual void Scale();
public virtual void Mirror();
public virtual void Jump();
public virtual void ApplyMatrixToModelMx();
public virtual void GetModelMxAs3x4();
public virtual void GetMinMaxForAbsoluteXYZ();
public virtual void HighlightVolumeColor()
}
-----------------------------------------------------------------------------------------
public abstract class CELemBase1D : CElemBase
{
// - public override CElemBase Clone();
// - public override void GenerateVertices();
// - public override int CreateGLcalls();
public override void GetMxOrigin();
public override void SetMxOrigin(double x,
double y, double z) { }
public override void Translate();
public override void Rotate();
public override void Scale();
public override void Mirror();
public override void Jump();
public override void ApplyMatrixToModelMx();
public override void GetModelMxAs3x4();
public override void
GetMinMaxForAbsoluteXYZ();
public virtual void
MakeHomegeneousMatrix16();
}
-----------------------------------------------------------------------------------------
public abstract class CELemBase2D : CElemBase1D
{
public override CElemBase Clone();
public override void GenerateVertices();
public override void CreateGLcalls();
public override void GetMxOrigin();
public override void GetMxAxisX();
public override void GetMxAxisY();
public override void GetMxAxisZ();
public override void Translate();
public override void Rotate();
public override void Scale();
public override void Mirror();
public override void Jump();
public override void ApplyMatrixToModelMx();
public override void GetModelMxAs3x4();
}
-----------------------------------------------------------------------------------------
public abstract class CELemBase3D : CElemBase2D
{
public override CElemBase Clone();
public override int GenerateVertices();
public override void CreateGLcalls();
}
-----------------------------------------------------------------------------------------
public class CELemElbow3D : CElemBase3D
{
public override CElemBase Clone();
public override int GenerateVertices();
public override void CreateGLcalls();
}
Simple
Scenario to Kick Off This Conversion
2011-March-24 |
Scenario
(1) Start Application
MainWindow::constructor
pDoc = new CDoc(this);
// Create a default view - same as New Window
miNewWindow_Click(null, null);
(2) Enter FM-command: CreateBox
MainWindow::miFMbox_Click
pDoc.OnFMCreateBox()
===> GDoc::OnFMCreateBox()
m_pFM = new CFM_createBox (m_pData)
InitializeFM()
(3) In FM_createBox, click Viewport --> This "creates" a new box
GView::UserControl_PrevMouseLeftButtonDown
CFM_base pFM = m_pdoc.GetActiveFM()
pFM.EventForDEFPT (1, null) ------------------- CREATE BOX
(A)==> GFM_createBox::EventForDEFPT ()
CElemBase pE = new CElemBox()
m_pData.m_elemList.Add (pE)
InvalidateAllVpts()??
m_pDoc.OnDraw_WPF (this.myViewport, allVpts)
------> (C) ON DRAW
(4) In FM_createBox, click model --> This "modifies" the box
GView::Model_PrevMouseLeftButtonDown
CFM_base pFM = m_pdoc.GetActiveFM()
pFM.EventForSEL (1, null) -------------------- MODIFY BOX
(B)==> GFM_createBox::EventForSEL ()
///////////// - test of MODIFY box
CElemBox pE = m_pData.m_elemList[0] as CElemBox;
// Modify some elem attributes...
pE.m_width *= 2;
m_pDoc.OnDraw_WPF (this.myViewport, allVpts)
------> (C) ON DRAW
(C) GDoc::OnDraw_WPF (vpt, allVpts)
foreach (CView pV in m_viewList)
foreach (CElem pE in
m_pData.m_elemList)
pE.DrawElemOneVpt (out n3, out vec3) ------> (D) DRAW ELEM ONE VPT
(D)==> GElem::DrawElemOneVpt (out n3, out vec3, ...)
// Elem's own ViewMatrix...
CreateVertices() // -- no change needed
CreateGLcalls_WPF (out n3, out vec3)
MesgGeometry3D mesh = new...
mesh.TriangleINDEX
pV.MyViewport.Children.Add (model)
(5) R-click the viewport --> Real-time View rotation
GView::UserControl_PrevMouseRightButtonDown
myCamera.Position
myCamera.LookDirection
myCamera.FieldOfView
(6) R-click the model --> Just a Test to add geometry
GView::Model_PrevMouseRightButtonDown
m_pDoc.OnDraw_WPF_TEST
(this.myViewport, allVpts)
How to
create a new element
2011-March-27 |
CElemBox:: example
/////////////////////////////////////////////////////////////////////////////
public CElemBox(G.COLORREF color, int layer, CPoint3D pt, CPoint3D dir,
CPoint3D ori, double height, double width) : base(color, layer, 1, pt, dir, ori, height, width)
{
m_elemType = G.ELEM_TYPE.ET_BOX;
m_totalVertex = 4;
}
/////////////////////////////////////////////////////////////////////////////
public override int GenerateVertices() // public virtual???????
{
double w = m_width / 2.0f;
double h = m_height / 2.0f;
m_pVertex2D = new CPoint2D [m_totalVertex ];
CPoint2D pt0 = new CPoint2D(w, h); m_pVertex2D[0] = pt0;
CPoint2D pt1 = new CPoint2D(w, -h); m_pVertex2D[1] = pt1;
CPoint2D pt2 = new CPoint2D(-w, -h); m_pVertex2D[2] = pt2;
CPoint2D pt3 = new CPoint2D(-w, h); m_pVertex2D[3] = pt3;
return 4; // ?
}
/////////////////////////////////////////////////////////////////////////////
public override void CreateGLcalls_WPF(out int n3, out CPoint3D[,] vec3)
{
// Create calls to OpenGL using vertices in m_generatedPts[i] qaz
n3 = 2; // 2 triangles
vec3 = new CPoint3D[3, 100];
vec3[0, 0] = new CPoint3D(m_pVertex2D[0].x, m_pVertex2D[0].y, 0.0f);
vec3[0, 1] = new CPoint3D(m_pVertex2D[1].x, m_pVertex2D[1].y, 0.0f);
vec3[0, 2] = new CPoint3D(m_pVertex2D[2].x, m_pVertex2D[2].y, 0.0f);
vec3[1, 0] = new CPoint3D(m_pVertex2D[2].x, m_pVertex2D[2].y, 0.0f);
vec3[1, 1] = new CPoint3D(m_pVertex2D[3].x, m_pVertex2D[3].y, 0.0f);
vec3[1, 2] = new CPoint3D(m_pVertex2D[0].x, m_pVertex2D[0].y, 0.0f);
ApplyMatrixToVec(n3, ref vec3);
//2011-3-14 was CreatePolygonWithNormal (4, vertex, 3,2,1,0);
}
CElemBase2D::
/////////////////////////////////////////////////////////////////////////////
public void ApplyMatrixToVec(int n3, ref CPoint3D[,] vec3)
{
// Apply elem's matrix to each vertex... m_matrix
for (int i = 0; i < n3; i++)
{
vec3[0, i] = m_matrix.TransformPoint(vec3[0, i]);
vec3[1, i] = m_matrix.TransformPoint(vec3[1, i]);
vec3[2, i] = m_matrix.TransformPoint(vec3[2, i]);
}
}
CElemBase::
/////////////////////////////////////////////////////////////////////////////
public void DrawElemOneVpt_WPF(out int n3, out CPoint3D[,] vec3)
{
GenerateVertices();
CreateGLcalls_WPF(out n3, out vec3); // Apply Elem's own matrix, etc.....
}
CDoc::
/////////////////////////////////////////////////////////////////////////////
public void OnDraw_WPF(Viewport3D vpt, bool bOneVptOnly = false) // 2011-3-22
{
// In the VC++ G system, CView::OnDraw drew everything:
// - DrawAllElems
// - DrawCurPlane
// - DrawAllTempElems
// - DrawRubberband3D
// - DrawZoomBox
// - DrawRubberband2D
// So, we have to do the same here....
///////////////////////////////////////////////////////
//---------- DrawAllElems -------------------
///////////////////////////////////////////////////////
// Most cases require all viewports to be updated
foreach (CView pV in m_viewList)
{
foreach (CElemBase1D pE in m_pData.m_elemList)
{
Colors color;
int n3 = 0;
CPoint3D[,] vec3 = new CPoint3D[3, 100];
pE.DrawElemOneVpt_WPF(out n3, out vec3);
///////////////////////////////////////// Create model
MeshGeometry3D mesh = new MeshGeometry3D();
///////////////////////////////////////// Create model
for (int i = 0; i < n3; i++)
{
int ii = i * 3;
Point3D pp0 = new Point3D(vec3[0, i].x, vec3[0, i].y, vec3[0, i].z);
Point3D pp1 = new Point3D(vec3[1, i].x, vec3[1, i].y, vec3[1, i].z);
Point3D pp2 = new Point3D(vec3[2, i].x, vec3[2, i].y, vec3[2, i].z);
mesh.Positions.Add(pp0);
mesh.Positions.Add(pp1);
mesh.Positions.Add(pp2);
mesh.TriangleIndices.Add(ii);
mesh.TriangleIndices.Add(ii + 2);
mesh.TriangleIndices.Add(ii + 1);
Vector3D norml = CalculateNormal(pp2, pp1, pp0); // bad - (pp0, pp1, pp2);
mesh.Normals.Add(norml);
mesh.Normals.Add(norml);
mesh.Normals.Add(norml);
}
Material matl = new DiffuseMaterial(new SolidColorBrush(Colors.Yellow));
GeometryModel3D geo = new GeometryModel3D(mesh, matl);
ModelVisual3D model = new ModelVisual3D();
model.Content = geo;
///////////////////////////////// Add model to viewport
if (bOneVptOnly)
{
vpt.Children.Add(model); // This vpt only
//-------------------------------------------------- Lihgt
// vpt.Children.Add(model4light); // add light
break;
}
pV.myViewport.Children.Add(model);
///////////////////////////////// Add model to viewport
}
//--------------------------------------------------------------- Lihgt
ModelVisual3D model4light = new ModelVisual3D();
DirectionalLight light = new DirectionalLight();
light.Color = Colors.White; // Green; // White;
light.Direction = new Vector3D(11, -21, -111);//(-1, 1, -5);
model4light.Content = light;
pV.myViewport.Children.Add(model4light); // add light
//--------------------------------------------------------------- Lihgt
}
VIew
Creation / Initialization / OnSize()
2011-May-26 |
/////////////////////////////////////////////////////////////////////////////
Main :: miNewWindow_Click (object sender, RoutedEventArgs e)
{
//------------------------------------------------- A NEW VIEWPORT
CView pV = new CView(pDoc, pDoc.m_pData);
pDoc.m_viewList.Add(pV);
//------------------------------------------------- MDI Creation
MdiCild mdiView = new MdiChild()
//------------------------------------------------- OnInitialUpdate
pV.OnInitialUpdate ();
// In MFC's Doc/View architecture, OnInitialUpdate is called immediately after the view is attached
// to the document. This is where the view's initialization should be done.
/////////////////////////////////////////////////////////////////////////////
CView :: constructor
{
//-------------- mainly member data initialization
/////////////////////////////////////////////////////////////////////////////
CView :: OnInitialUpdate ()
{
//-------------- initialization
OnSize (mdi.Width, mdi.Height)
Setup2Projection ()
Setup2UpVector ()
Setup3Light ()
/////////////////////////////////////////////////////////////////////////////
CView :: OnSize (x, y)
{
//------------------------------------------------- A NEW VIEWPORT
m_pixSizeX, Y
UpdateOrthoSizeGivenNewPerspectiveSetting ()
---> Setup1ViewAspectRatio ()
Menu:
Window --> New Window (viewport)
2011-March-29 |
New Viewport Creation - MainWindow::
/////////////////////////////////////////////////////////////////////////////
private void miNewWindow_Click(object sender, RoutedEventArgs e)
{
//------------------------------------------------- CREATE A NEW VIEWPORT
// (1) Create a CView instance...
CView pV = new CView(pDoc, pDoc.m_pData);
pDoc.m_viewList.Add(pV);
// (2) Create an Mdi instance...
MdiCild mdiView = new MdiChild()
{ Title = "WPF 3D - CView",
Content = pV,
Width = 600, MinWidth = 150,
Height = 400, MinHeight = 150,
MinimizeBox = true, MaximizeBox = true,
};
Canvas.SetLeft(mdiView, 600);
Canvas.SetTop(mdiView, 150);
// Save in 2 places: (1) Mdi Container (2) data member
Container.Children.Add(mdiView);
pDoc.m_mdiViewList.Add(mdiView);
pDoc.m_viewList.Add(pV);
// (3) Initialize view attributes...
pV.OnInitialUpdate(600, 400);
// In MFC's Doc/View architecture, OnInitialUpdate is called immediately after the view is attached
// to the document. This is where the view's initialization should be done.
// (4) Camera setup...
pV.Setup2Projection();
pV.Setup2UpVector();
-- pV.myCamera.Position = new Point3D(-20, 0, 0);
-- pV.myCamera.LookDirection = new System.Windows.Media.Media3D.Vector3D(1, 0, 0);
-- pV.myCamera.UpDirection = new System.Windows.Media.Media3D.Vector3D(0, 0, 1);
-- pV.myCamera.FieldOfView = 30;
-- pV.myCamera.NearPlaneDistance = 0.1;
-- pV.myCamera.FarPlaneDistance = 200;
// (5) Lighting...
ModelVisual3D model4light = new ModelVisual3D();
DirectionalLight light = new DirectionalLight();
light.Color = Colors.White; // Green;
light.Direction = new Vector3D(1, -21, -111);
model4light.Content = light;
pV.myViewport.Children.Add(model4light); // add light to vpt
//------------------------------------------------- CREATE A NEW VIEWPORT
}
WPF Rendering
Flow : OnDraw_WPF
2011-May-26 |
(A) Create a New Element
/////////////////////////////////////////////////////////////////////////////
CView::UserControl_PreviewMouseLeftButtonDown (object sender, MouseButtonEventArgs e)
{
CFM_base pFM = m_pDoc.GetActiveFM ();
pFM.EventForIND ();
m_pDoc.OnDraw_WPF (m_pData.m_OnDrawFlag, this);
}
/////////////////////////////////////////////////////////////////////////////
CFM_createBox3d::EventForIND ()
{
//------------------------------------------------- CREATE A NEW ELEMENT
// Clear this list every time
m_pData.m_elemNewlyCreatedList.Clear ();
CElemBase pE1 = new CElemBox3d(G.COLORREF.A, layer, m_ptIND, new CPoint3D(1, 0, 0), new CPoint3D(1, 0, 1), 0.1, 0.1, 0.5);
m_pData.m_elemList.Add (pE1);
m_pData.m_elemNewlyCreatedList.Add (pE1);
CElemBase pE2 = new CElemBox3d(G.COLORREF.A, layer, m_ptIND, new CPoint3D(-1, 0, 0), new CPoint3D(1, 0, 1), 0.1, 0.1, 0.5);
m_pData.m_elemList.Add (pE2);
m_pData.m_elemNewlyCreatedList.Add (pE2);
m_pData.m_OnDraw_flag = 1; // Draw only newly created elements on all vpts
}
/////////////////////////////////////////////////////////////////////////////
CDoc::OnDraw_WPF (int flag, CView pVOnlyOne = null)
{
------------------------------------------------------------
// flag = 1: Draw only newly created elems in all vpts
{
foreach (CView pV in m_viewList)
{
DrawNewlyCreatedElems (pV);
//------------------ Draw Axis axes
//------------------ Draw Current plane
}
------------------------------------------------------------
// flag = 2: Undraw an elem in all vpts
{
foreach (CView pV in m_viewList)
{
UndrawThisElem (pV, m_pData.m_pElemUndraw);
}
------------------------------------------------------------
// flag = 3: Draw all elems in only one vpt
{
DrawAllElems (pVOnlyOne);
//------------------ Draw Axis axes
//------------------ Draw Current plane
}
/////////////////////////////////////////////////////////////////////////////
CDoc::DrawAllElems (CView pV)
{
foreach (CElemBase1D pE in m_pData.m_elemList)
{
DrawElemOneVpt (pE, pV);
}
}
/////////////////////////////////////////////////////////////////////////////
CDoc::DrawNewlyCreatedElems (CView pV)
{
foreach (CElemBase1D pE in m_pData.m_elemNewlyCreatedList)
{
DrawElemOneVpt (pE, pV);
}
}
/////////////////////////////////////////////////////////////////////////////
CDoc::UndrawThisElem (CView pV, CElemBase pElemToDelete)
{
int index = 0;
foreach (CElemBase pE in pV.m_elemList)
{
if (pE == pElemToDelete)
{
index = 1;
ModelVisual3D model = pV.m_modelVisual3DList (index);
pV.myViewport.Children.Remove (model);
break;
}
}
}
/////////////////////////////////////////////////////////////////////////////
CDoc::DrawElemOneVpt (CElemBase pE, CView pV)
{
Colors color;
int n3 = 0;
CPoint3D[,] vec3 = new CPoint3D[3, 100];
pE.GenerateVerticesAndCreateWPFcalls (out n3, out vec3);
MeshGeometry3D mesh = new MeshGeometry3D();
for (int i = 0; i < n3; i++)
{
Point3D pp0 = new Point3D(vec3[0, i].x, vec3[0, i].y, vec3[0, i].z);
mesh.Positions.Add (pp0,,,,);
mesh.TriangleIndices.Add (ii,,,,);
Vector3D norml = CalculateNormal(pp0, pp1, pp2);
mesh.Normals.Add (norml,,,,);
}
Material mat = new DiffuseMaterial(new SolidColorBrush(Colors.LightBlue));
GeometryModel3D geo = new GeometryModel3D(mesh, mat);
ModelVisual3D model = new ModelVisual3D ();
model.Content = geo;
pV.myViewport.Children.Add (model); // Add model to viewport
// Save for future delete...
pV.m_modelVisual3DList.Add (model);
pV.m_elemList.Add (pE);
}
(B) Delete an Element
/////////////////////////////////////////////////////////////////////////////
CView::UserControl_PreviewMouseLeftButtonDown (object sender, MouseButtonEventArgs e)
{
//------------------------------------------------- GET CURRENT FM
CFM_base pFM = m_pDoc.GetActiveFM ();
pFM.EventForIND ();
m_pDoc.OnDraw_WPF (m_pData.m_OnDrawFlag, this);
}
/////////////////////////////////////////////////////////////////////////////
CFM_createBox3d::EventForIND ()
{
// ---- Identify the element to be deleted
//------------------------------------------------- REMOVE THIS ELEM FROM ELEM LIST
m_pData.m_elemList.Remove (pElemToDelete);
m_pData.m_OnDraw_flag = 2; // Undraw an element on all vpts
m_pData.m_pElemUndraw = pElemToDelete;
}
/////////////////////////////////////////////////////////////////////////////
CDoc::OnDraw_WPF (int flag, CView pVOnlyOne = null)
{
// flag = 1: Draw only newly created elems in all vpts
{
foreach (CView pV in m_viewList)
{
DrawNewlyCreatedElems (pV);
//------------------ Draw Axis axes
//------------------ Draw Current plane
}
}
// flag = 2: Undraw an elem in all vpts
{
foreach (CView pV in m_viewList)
{
UndrawThisElem (pV, m_pData.m_pElemUndraw);
}
}
// flag = 3: Draw all elems in only one vpt
{
DrawAllElems (pVOnlyOne);
//------------------ Draw Axis axes
//------------------ Draw Current plane
}
}
/////////////////////////////////////////////////////////////////////////////
CDoc::UndrawThisElem (CView pV, CElemBase pElemToDelete)
{
int index = 0;
foreach (CElemBase pE in pV.m_elemList)
{
if (pE == pElemToDelete)
{
index = 1;
ModelVisual3D model = pV.m_modelVisual3DList (index);
pV.myViewport.Children.Remove (model);
break;
}
}
}
(C) When a New Viewport Popped
/////////////////////////////////////////////////////////////////////////////
MainWindow::miNewViewport_Click(object sender, RoutedEventArgs e)
{
//------------------------------------------------- GET CURRENT FM
// (1) Create a CView instance ---------------------- CREATE NEW VIEWPORT
CView pV = new CView (pDoc, pDoc.m_pData);
pDoc.m_viewList.Add (pV);
// (2) Create an Mdi instance ------------------------ CREATE MDI INSTANCE
MdiChild mdiChd = new MdiChild()
Canvas.SetLeft(mdiChd, 600);
Canvas.SetTop(mdiChd, 150);
// Save in 2 places: (1) Mdi Container (2) data member
Container.Children.Add(mdiChd);
pDoc.m_mdiViewList.Add(mdiChd);
pV.m_mdiChild = mdiChd;
// (3) Initialize view attributes...
pV.OnInitialUpdate(); // ((int)mdiWidth, (int)mdiHeight);
// (4) Camera setup ------------------------------------ CAMERA
pV.Setup2Projection();
pV.Setup2UpVector();
// (5) Lighting ----------------------------------------- LIGHT
ModelVisual3D model = new ModelVisual3D();
DirectionalLight lightDir = new DirectionalLight();
AmbientLight lightAmb = new AmbientLight();
PointLight lightPnt = new PointLight();
pV.myViewport.Children.Add(model); // add light to vpt
// (6) Draw all elements -------------------------- DRAW ELEMENTS
pDoc.OnDraw_WPF (3, pV); // Draw all elemes in one vpt
}
/////////////////////////////////////////////////////////////////////////////
CDoc::OnDraw_WPF (int flag, CView pVOnlyOne = null)
{
// flag = 1: Draw only newly created elems in all vpts
{
foreach (CView pV in m_viewList)
{
DrawNewlyCreatedElems (pV);
//------------------ Draw Axis axes
//------------------ Draw Current plane
}
}
// flag = 2: Undraw an elem in all vpts
{
foreach (CView pV in m_viewList)
{
UndrawThisElem (pV, m_pData.m_pElemUndraw);
}
}
// flag = 3: Draw all elems in only one vpt
{
DrawAllElems (pVOnlyOne);
//------------------ Draw Axis axes
//------------------ Draw Current plane
}
}
/////////////////////////////////////////////////////////////////////////////
CDoc::DrawAllElems (CView pV)
{
foreach (CElemBase1D pE in m_pData.m_elemList)
{
DrawElemOneVpt (pE, pV);
}
}
/////////////////////////////////////////////////////////////////////////////
CDoc::DrawElemOneVpt (CElemBase pE, CView pV)
{
Colors color;
int n3 = 0;
CPoint3D[,] vec3 = new CPoint3D[3, 100];
pE.GenerateVerticesAndCreateWPFcalls (out n3, out vec3);
MeshGeometry3D mesh = new MeshGeometry3D();
for (int i = 0; i < n3; i++)
{
Point3D pp0 = new Point3D(vec3[0, i].x, vec3[0, i].y, vec3[0, i].z);
mesh.Positions.Add (pp0,,,,);
mesh.TriangleIndices.Add (ii,,,,);
Vector3D norml = CalculateNormal(pp0, pp1, pp2);
mesh.Normals.Add (norml,,,,);
}
Material mat = new DiffuseMaterial(new SolidColorBrush(Colors.LightBlue));
GeometryModel3D geo = new GeometryModel3D(mesh, mat);
ModelVisual3D model = new ModelVisual3D ();
model.Content = geo;
pV.myViewport.Children.Add (model); // Add model to viewport
// Save for future delete...
pV.m_modelVisual3DList.Add (model);
pV.m_elemList.Add (pE);
}
Function Mode (FM) Messages
Printing Mechanism
2011-June-04 |
I decided to use a delegate to pass FMPrintMessages() down to Class FM_command
to handle FM prompt message display on the G-System desktop.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
MainWindow::
------------------------------------------------------------------------------------
public void FMPrintMessages () // to be sent as Delegate to -> Doc -> FM base
{
if (pDoc != null)
{
lblFMcommand.Content = pDoc.m_pData.FM_command;
lblFMprompt.Content = pDoc.m_pData.FM_prompt;
lblSystemFeedback.Content = pDoc.m_pData.FM_systemFeedback;
lblKeyinEcho.Content = pDoc.m_pData.FM_keyinEcho;
// clear each time
pDoc.m_pData.FM_prompt = "";
pDoc.m_pData.FM_systemFeedback = "";
pDoc.m_pData.FM_keyinEcho = "";
}
}
------------------------------------------------------------------------------------
pDoc = new CDoc (this, FMPrintMessages);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CDoc::
------------------------------------------------------------------------------------
public FMPrintMessagesDelegate FMPrintMessages;
------------------------------------------------------------------------------------
public CDoc
(Window window, FMPrintMessagesDelegate d)
{
this.window = window;
this.FMPrintMessages
= d;
m_pFM
= new CFM_createPoint (m_pData,
FMPrintMessages);
OnNewDocument();
}
------------------------------------------------------------------------------------
public void OnCreatePoint()
{ m_pFM = new CFM_createPoint (m_pData,
FMPrintMessages);
InitializeFM(); }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CFM_base::
------------------------------------------------------------------------------------
public delegate void
FMPrintMessagesDelegate ();
// delegate declaration
------------------------------------------------------------------------------------
public int pxs;
public int cxs;
public FMPrintMessagesDelegate
FMPrintMessages;
//
save as data member
public string
m_promptMessage;
------------------------------------------------------------------------------------
public CFM_base (CData pData,
FMPrintMessagesDelegate d)
{
m_pData = pData;
this.FMPrintMessages
= d;
pxs
= 0;
cxs
= 1;
}
------------------------------------------------------------------------------------
public virtual void NXS (
int nxs = 0 )
{
int
n = ( 0 == nxs ) ? cxs : nxs;
pxs
= cxs; cxs = n;
//
Invoke delegate
this.FMPrintMessages
();
CommonTaskForNXS ( nxs );
}
------------------------------------------------------------------------------------
public void FM_command (string s)
{ m_pData.FM_command = s; }
public void SystemFeedbackMessage (string s)
{ m_pData.FM_systemFeedback = s; }
public void PromptMessage (string s)
{ m_pData.FM_prompt = s; }
public void KeyinEchoMessage (string s)
{ m_pData.FM_keyinEcho = s; }
------------------------------------------------------------------------------------
public CFM_baseP
(CData pData, FMPrintMessagesDelegate d) : base (pData, d)
public CFM_baseT (CData pData,
FMPrintMessagesDelegate d) : base (pData, d)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CFM_createPoint::
-- example --
------------------------------------------------------------------------------------
public CFM_createPoint
(CData pData, FMPrintMessagesDelegate d) // constructor
: base (pData, d)
{
FM_command
( "FM Create Point" );
NXS (1);
SetSubmenu();
}
------------------------------------------------------------------------------------
public override void InitializeFM
()
{
}
------------------------------------------------------------------------------------
public override void NXS
(int nxs)
{
switch (nxs)
{
case 1:
PromptMessage
( "Indicate to create a point"
);
break;
case 2:
PromptMessage
( "Indicate to create another point"
);
break;
case 3:
PromptMessage
( "Indicate to create yet
another point )";
break;
}
base.NXS (nxs);
// Call base function
at the end
}
------------------------------------------------------------------------------------
public override void
EventForIND ()
{
m_pData.m_elemNewlyCreatedList.Clear ();
switch (nxs)
{
case 1:
CElemBase pE1 = new CElemBox3d (
. . . , m_ptIND, . . . );
m_pData.m_elemList.Add (pE1);
m_pData.m_elemNewlyCreatedList.Add
(pE1);
SystemFeedbackMessage (
"Box 3D
created successfully"
);
NXS (2);
break;
case 2:
. . . . .
break;
case 3:
. . . . .
break;
}
m_pData.m_OnDraw_flag = 1; //
1 = DrawAllElems, 2 = UndrawThisElem
}
Element Creation Paradigm
2011-June-10 |
In this WPF system, the following element creation paradigm has been established.
Whenever a new element is to be created, this paradigm must be followed:
/////////////////////////////////////////////////////////////////////////////
CView::UserControl_PreviewMouseLeftButtonDown (object sender, MouseButtonEventArgs e)
{
CFM_base pFM = m_pDoc.GetActiveFM ();
pFM.EventForIND ();
m_pDoc.OnDraw_WPF (m_pData.m_OnDrawFlag, this);
}
/////////////////////////////////////////////////////////////////////////////
CFM_createElbow::EventForIND ()
{
m_pData.CreateElbow (m_ptIND, 3, 5);
NXS (2);
InvalidateAllVpts_WPF (1); // Draw newly created elems in all viewports
}
/////////////////////////////////////////////////////////////////////////////
CData::CreateElbow (pt, a, b)
{
m_feedbackMessage = 1;
FactoryForElemOnCP (ET_ELBOW, pt, a, b);
}
/////////////////////////////////////////////////////////////////////////////
CData::FactoryForElemOnCP / FactoryForCloneElem / FactoryForDittoElem
{
pE = NewElem (type, pt, CurPlane.X, CurPlane.Y, a, b, c, d)
RegisterNewElem (pE);
}
/////////////////////////////////////////////////////////////////////////////
CData::NewElem (type, pt, CurPlane.X, CurPlane.Y, a, b, c,
d)
{
switch (type)
{
case ET_POINT:
pE = new
CElemPoint (---);
case ET_ELBOW:
pE = new
CElemElbow (---);
case ET_BOX:
pE = new
CElemBox (---);
}
}
/////////////////////////////////////////////////////////////////////////////
CData::RegisterNewElem (pE) / RegisterNewDitto (pE))
{
m_pElemCur = pE;
m_elemList.Add (pE);
m_elemNewlyCreatedList.Add (pE);
//
Cleared in OnDraw_WPF
}
/////////////////////////////////////////////////////////////////////////////
CFM_base::InvalidateAllVpts_WPF (flag)
{
m_pData.m_OnDraw_flag = flag; // 1 = DrawAllElems, 2 = UndrawThisElem
}
/////////////////////////////////////////////////////////////////////////////
Visual Cue Display
Scheme (1) --- Temporary Element / Lines
2011-June-19 |
Temp elem (lines) are used in FM command for visual cues...
/////////////////////////////////////////////////////////////////////////////
CDoc::OnDraw_WPF
{
DrawAllElems (pV);
DrawAbsoluteAxes (pV);
DrawCurPlane (pV);
DrawTempElem (pV);
// Clear this list
everytime
m_pData.m_elemNewlyCreatedList.Clear();
}
CDoc::DrawTempElem
(CView pV)
{
// Make sure to remove first...
ScreenSpaceLines3D line1 =
pV.m_tempLineWPF1;
line1.Points.Clear ();
// importnt to clear
pV.myViewport.Children.Remove(line1);
ScreenSpaceLines3D line2 =
pV.m_tempLineWPF2;
line2.Points.Clear ();
// importnt to clear
pV.myViewport.Children.Remove(line2);
//-----------------------------------------------------------
Line 1
foreach (CPoint3D p in
m_pData.m_tempLineWPFArraySingle1)
{
line1.Points.Add(pp1);
line1.Points.Add(pp2);
}
foreach (CPoint3D p in
m_pData.m_tempLineWPFArrayMulti1)
{
line1.Points.Add(pp1);
line1.Points.Add(pp2);
}
line1.Thickness =
m_pData.m_tempLineWPFThickness1;
line1.Color = Colors.BlueViolet;
pV.myViewport.Children.Add(line1);
//----------------------------------------------------------- Line 2
//----------------------------------------------------------- Line 3
}
/////////////////////////////////////////////////////////////////////////////
CView::
{
// IMPORTANT NOTE: These have to be declared here in View; cannot be in
Doc
// (nor in Data, for Data has
no scope for Lines3D). If declared in Doc,
// an exception is raised when
there are more than one viewport, because
// one instance of
ScreenSpaceLines3D cannot be added to myViewport
// of multiple Views. <
2011-6-19>
// Temporary lines
used by FM commands...
public ScreenSpaceLines3D
m_tempLineWPF1 = new ScreenSpaceLines3D();
public ScreenSpaceLines3D
m_tempLineWPF2 = new ScreenSpaceLines3D();
public ScreenSpaceLines3D
m_tempLineWPF3 = new ScreenSpaceLines3D();
// Current plane &
Keyin coordinnates...
public ScreenSpaceLines3D
m_visualCueCurPlane = new ScreenSpaceLines3D();
public ScreenSpaceLines3D
m_visualCueCoordRCS = new ScreenSpaceLines3D();
// Absolute axes (RGB)...
public ScreenSpaceLines3D
m_visualCueAbsAxisR = new ScreenSpaceLines3D();
public ScreenSpaceLines3D
m_visualCueAbsAxisG = new ScreenSpaceLines3D();
public ScreenSpaceLines3D
m_visualCueAbsAxisB = new ScreenSpaceLines3D();
// Visual cues for
real-time viewing...
public ScreenSpaceLines3D
m_visualCueViewing1 = new ScreenSpaceLines3D();
public ScreenSpaceLines3D
m_visualCueViewing2 = new ScreenSpaceLines3D();
public ScreenSpaceLines3D
m_visualCueViewing3 = new ScreenSpaceLines3D();
public ScreenSpaceLines3D
m_visualCueViewing4 = new ScreenSpaceLines3D();
public ScreenSpaceLines3D
m_visualCueViewing5 = new ScreenSpaceLines3D();
}
/////////////////////////////////////////////////////////////////////////////
CData::
{
//--------------------------------------- temp line 1
public List<CPoint3D>
m_tempLineWPFArraySingle1 = new List<CPoint3D>();
public List<CPoint3D>
m_tempLineWPFArrayMulti1 = new List<CPoint3D>();
public int m_tempLineWPFColor1 = 1;
public int m_tempLineWPFThickness1 =
1;
//--------------------------------------- temp line 2
public List<CPoint3D>
m_tempLineWPFArraySingle2 = new List<CPoint3D>();
public List<CPoint3D>
m_tempLineWPFArrayMulti2 = new List<CPoint3D>();
public int m_tempLineWPFColor2 = 1;
public int m_tempLineWPFThickness2 =
1;
/////////////////////////////////////////////////////////////////////////////
CFM_base::TempLineWPFClear1,
2, 3 ()
{
m_pData.m_tempLineWPFArraySingle1.Clear ();
m_pData.m_tempLineWPFArrayMulti1.Clear ();
}
CFM_base::TempLineWPFStart1,
2, 3 (color,
thickness)
{
m_pData.m_tempLineWPFColor1 = color;
m_pData.m_tempLineWPFThickness1 =
color;
}
CFM_base::TempLineWPF1,
2, 3 (p1, p2)
{
m_pData.m_tempLineWPFArraySingle1.Add (p1);
m_pData.m_tempLineWPFArraySingle1.Add (p2);
}
CFM_base::TempLineWPFArray1,
2, 3 (int flag, CPoint3D[]
pArray)
{
foreach (CPoint3D p in pArray) m_pData.m_tempLineWPFArrayMulti1.Add (p);
if (flag == 1)
m_pData.m_tempLineWPFArrayMulti1.Add(pArray[0]);
}
/////////////////////////////////////////////////////////////////////////////
CFM_createBox::EventForIND ()
{
case 1:
TempLineWPFClearAll();
//
TempLineWPFClear1();
//
TempLineWPFClear2();
m_pData.CreateBox(m_ptIND, 1.0, 0.5);
SystemFeedbackMessage("Box created by IND");
int
color = 1;
int
thickness = 5;
TempLineWPFStart1 (color, thickness);
TempLineWPF1 (p1, m_ptIND);
TempLineWPF1 (p2, m_ptIND);
CPoint3D[] pArray = {new CPoint3D(0, -1, -1),new CPoint3D(0, -1, -3),new
CPoint3D(0, -2, -5) };
TempLineWPFArray1 (1, pArray);
// flag = 1 : close loop
NXS(2);
break;
InvalidateAllVpts_WPF (1);
}
Visual Cue Display
Scheme (2) --- Viewing Free Rot/Pan/Zoom
2011-June-19 |
Users: View::BeginRealTimeFreeRotation / FreePan / FreeZoom
View::UserControl_PrevMouseRightButtonUp()
/////////////////////////////////////////////////////////////////////////////
CView::
{
public ScreenSpaceLines3D m_visualCueViewing1 = new ScreenSpaceLines3D();
public ScreenSpaceLines3D
m_visualCueViewing2 = new ScreenSpaceLines3D();
public ScreenSpaceLines3D
m_visualCueViewing3 = new ScreenSpaceLines3D();
public ScreenSpaceLines3D
m_visualCueViewing4 = new ScreenSpaceLines3D();
public ScreenSpaceLines3D
m_visualCueViewing5 = new ScreenSpaceLines3D();
}
CView:: VisualCueViewingClear1()
{
this.myViewport.Children.Remove (m_visualCueViewing1);
m_visualCueViewing1.Points.Clear ();
}
CView:: VisualCueViewingStart1 (Color color, int
thickness)
{
m_visualCueViewing1.Color = color;
m_visualCueViewing1.Thickness =
thickness;
}
CView:: VisualCueViewingPoint1 (p1, p2)
{
ViewingVisCuePoint1 (pp1, pp2);
}
CView:: VisualCueViewingEnd1 ()
{
this.myViewport.Children.Add
(m_visualCueViewing1);
}
Visual Cue Display
Scheme (3) --- Key-in Coordinate Rect/Cyl/Sph
2011-June-20 |
Visual cue for the key-in coordinate is issued by Main:: txtKeyinPad_TextChanged(
/////////////////////////////////////////////////////////////////////////////
CView::
{
public ScreenSpaceLines3D m_visualCueCoordRCS = new
ScreenSpaceLines3D();
}
/////////////////////////////////////////////////////////////////////////////
CDoc:: DrawCoordinateRCS (CView pV)
{
// Clear first....
ClearCoordianteRCS ()
ScreenSpaceLines3D line= pV.m_visualCueCoordRCS;
line.Thickness = width;
line.Color = c;
line.Points.Add(p0);
line.Points.Add(p1);
pV.myViewport.Children.Add (line);
}
CDoc:: ClearCoordianteRCS(CView pV)
// One viewport
{
pV.myViewport.Children.Remove (pV.m_visualCueCoordRCS);
m_visualCueCurPlane.Points.Clear ();
// importnt to clear
}
/////////////////////////////////////////////////////////////////////////////
Main:: txtKeyinPad_TextChanged(object sender,
TextChangedEventArgs e)
{
try
{
// Clear temp display...
only after ENTER
m_pDoc.ClearCoordianteRCS();
// All vpts
m_pDoc.m_pFM.m_ptKEY3 = m_pDoc.GetKeyCoordinate();
/////////////////////////////////////////////////////////////////////////////
CDoc:: GetKeyCoordinate()
{
DrawCoordinateRCS();
// All vpts
return ptAbs;
}
Visual Cue Display
Scheme (4) --- Current Plane
2011-June-20 |
Current plane must be redrawn every time....
/////////////////////////////////////////////////////////////////////////////
CView::
{
public ScreenSpaceLines3D m_visualCueCurPlane = new
ScreenSpaceLines3D();
}
/////////////////////////////////////////////////////////////////////////////
CDoc:: OnDraw_WPF
{
DrawAllElems (pV);
DrawAbsoluteAxes (pV);
DrawCurPlane (pV);
DrawTempElem (pV);
}
CDoc::
DrawCurPlane (CView pV)
{
// Clear first....
ClearCurPlane(pV);
ScreenSpaceLines3D line= pV.m_visualCueCurPlane;
line.Thickness = width;
line.Color = c;
line.Points.Add(p0);
line.Points.Add(p1);
pV.myViewport.Children.Add (line);
}
CDoc:: ClearCurPlane(CView pV)
// One viewport
{
pV.myViewport.Children.Remove(pV.m_visualCueCurPlane);
pV.m_visualCueCurPlane.Points.Clear();
}
/////////////////////////////////////////////////////////////////////////////
CDoc:: OnCurPlaneXy/Xz/Zy()
{
m_pData.m_pCurPlane.SetPresetPlaneXY();
DrawCurPlane();
// All vpts
}
Event Generation Sites
2011-June-21 |
Events are generated from two places: MainWindow and CView.
Main Window
/////////////////////////////////////////////////////////////////////////////
1. Menu Event
Main:: miOrthoXY_Click ()
----------> Doc:: OnOrthoUtilityXY ()
Main:: miOrthoXZ_Click ()
----------> Doc:: OnOrthoUtilityXZ ()
Main:: miCreateBox_Click ()
----------> Doc:: OnFMCreateBox () ---> m_pFM = new CFM_createBox
Main:: miElemRotate ()
----------> Doc:: OnFMElemRotate () ---> m_pFM = new CFM_elemRotate
/////////////////////////////////////////////////////////////////////////////
2. Key Event
Main:: Window_PreviewKeyDown ()
BEFORE_EventForInitialize ()
----------> View:: OnMMZoomLensAngle (delta);
----------> View:: OnMMPanTurnHead (delta);
----------> View:: OnMMZoomMoveCamera (delta);
----------> FM:: EventForESC ()
----------> FM:: EventForDEL ()
----------> FM:: EventForTAB ()
----------> FM:: EventForSPACE ()
----------> FM:: EventForARROW
AFTER_EventForOnDraw ()
/////////////////////////////////////////////////////////////////////////////
3. Coordinate Key-in Event
Main:: txtKeyinPad_TextChanged (txtKeyinPad_PreviewKeyDown)
BEFORE_EventForInitialize ()
----------> FM:: EventForKEY3 ()
----------> FM:: EventForKEY2 ()
----------> FM:: EventForKEY1 ()
----------> FM:: EventForDEFPT ()
AFTER_EventForOnDraw ()
/////////////////////////////////////////////////////////////////////////////
Main:: private CView BEFORE_EventForInitialize()
{
m_pDoc.m_pData.m_OnDraw_flag = 0;
CView pV = GetActiveViewport (); // Initialize flag to 0 before EventForXXX
m_pDoc.m_pViewEvent = pV; // view pointer of event-origin
return pV;
}
Main:: private void AFTER_EventForOnDraw()
{
m_pDoc.OnDraw_WPF (); // All vpts
txtKeyinPad.Focus();
}
CView
/////////////////////////////////////////////////////////////////////////////
1. Mouse Button Down / Up Event
View::
UserControl_PreviewMouseLeftButtonDown
BEFORE_EventForInitialize
()
BeginRealTimeFreeRotation (p)
---------->
FM:: EventForLBD
()
---------->
FM:: EventForDEFPT
()
AFTER_EventForOnDraw
()
View::
UserControl_PreviewMouseLeftButtonUp
BeginRealTimeFreePan (p)
BeginRealTimeFreeZoom (p)
---------->
FM:: EventForLBU
()
View::
UserControl_PreviewMouseRightButtonDown
BEFORE_EventForInitialize
()
---------->
FM:: EventForRBD
()
AFTER_EventForOnDraw
()
View::
UserControl_PreviewMouseRightButtonUp
---------->
FM:: EventForRBU
()
View::
UserControl_PreviewMouseDoubleClick
---------->
FM:: EventForLB2
()
---------->
FM:: EventForRB2
()
/////////////////////////////////////////////////////////////////////////////
2. Mouse Move Event
View:: UserControl_PreviewMouseMove
---------->
FM:: EventForMMV
()
---------->
OnMMPanSameOrien ()
---------->
OnMMPanTurnHead ()
---------->
OnMMZoomLensAngle ()
---------->
OnMMZoomMoveCamera ()
/////////////////////////////////////////////////////////////////////////////
3. Viewport Size Changed Event
View:: UserControl_SizeChanged
SetVptPixelSizeXYandRatio();
Setup2Projection();
Setup2UpVector();
UpdateVptExtentAndSizes();
/////////////////////////////////////////////////////////////////////////////
View:: private void
BEFORE_EventForInitialize
()
{
m_pDoc.m_pData.m_OnDraw_flag = 0;
// Initialize flag to 0
before EventForXXX
m_pDoc.m_pViewEvent = this;
// view pointer of
event-origin
}
View:: private void
AFTER_EventForOnDraw
()
{
m_pDoc.OnDraw_WPF (this);
lblViewCaption2.Content =
DateTime.Now.ToString();
}
WPF 3D Rendering Scheme
Revisited
2011-December-30 |
-----------------------------------------------------------------
public void OnDraw_WPF(CView pVOnlyOne = null)
{
// This is always called after
EventForXXX. FM processing the EventForXXX
// sets the flag via ....
if (bAllElems)
{
//------------------(1)----------------------- All elems
foreach
(CElemBase1D pE in m_pData.m_elemList)
{
// Check each elem's render capability...
SetRenderFlags(flag, pE, out nWire, out nShade);
if (nShade > 0) geo = CreateGeometryModel3D(pE); // Common for
Draw & Modify
if (nWire > 0) pE.GenerateVerticesAndCreateWPFcalls(out n2, out
vec2, out n3, out vec3, out segArray);
if (bAllVpts)
{ // ------------------------------ All vpts
foreach (CView pV in m_viewList)
{
Render(pE, pV, geo, n2, vec2, n3, vec3, segArray, nShade, nWire,
bModify, bDelete);
DrawTempElemOneVpt(pV);
-----------------------------------------------------------------
public GeometryModel3D CreateGeometryModel3D(CElemBase pE)
{
-----------------------------------------------------------------
public void Render(CElemBase pE, CView pV,
GeometryModel3D geo, int n2, CPoint3D[,] vec2, int n3,
CPoint3D[,] vec3, int[] segArray,
uint nShade, uint nWire, bool bModify, bool bDelete = false)
{
// This is the low-level WPF3D
renderer. The value of nShade and nWire controls
// the rendering. 1 for
single-render-object, 2 for multi-render-objects. Either 1 or 2
-----------------------------------------------------------------
/////////////////////////////////////////////////////////////////77//////////
public void
CREATE_SINGLE_SHADE(CElemBase pE, CView pV, GeometryModel3D geo)
{
ModelVisual3DG model = new ModelVisual3DG();
model.Content = geo;
//----------------------------- Apply "Transform" property
CViewMatrix m = pE.GetMatrix(); // elem's own matrix
Matrix3D mx = new Matrix3D(m.Xx, m.Xy, m.Xz, 0, m.Yx, m.Yy, m.Yz, 0,
m.Zx, m.Zy, m.Zz, 0, m.Ox, m.Oy, m.Oz, 1);
MatrixTransform3D tran = new MatrixTransform3D(mx);
//----------------------------- Apply "Transform" property
model.Transform = tran;
pV.myViewport.Children.Add(model);
model.m_pElem = pE; // save "data structure" pointer in "render"
pE.m_singleShadeDict.Add(pV, model); // save "render" side pointer
}
public void
MODIFY_SINGLE_SHADE(CElemBase pE, CView pV)
{
ModelVisual3D model = pE.m_singleShadeDict[pV];
//--- GeometryModel3D geo = CreateGeometryModel3D(pE);
//--- model.Content = geo;
//
This modify only works for "Transform" property change...
CViewMatrix m = pE.GetMatrix(); // elem's own matrix
Matrix3D mx = new Matrix3D(m.Xx, m.Xy, m.Xz, 0, m.Yx, m.Yy, m.Yz, 0,
m.Zx, m.Zy, m.Zz, 0, m.Ox, m.Oy, m.Oz, 1);
MatrixTransform3D tran = new MatrixTransform3D(mx);
model.Transform = tran;
}
public void
DELETE_SINGLE_SHADE(CElemBase pE, CView pV)
{
ModelVisual3D model = pE.m_singleShadeDict[pV];
pV.myViewport.Children.Remove(model);
}
public void
HIDE_SINGLE_SHADE(CElemBase pE, CView pV)
public void
UNHIDE_SINGLE_SHADE(CElemBase pE, CView pV)
/////////////////////////////////////////////////////////////////77//////////
public void
CREATE_MULTI_SHADE(CElemBase pE, CView pV, int[] segArray, CPoint3D[,]
vec2)
public void
MODIFY_MULTI_SHADE(CElemBase pE, CView pV)
public void
DELETE_MULTI_SHADE(CElemBase pE, CView pV)
public void
HIDE_MULTI_SHADE(CElemBase pE, CView pV)
public void
UNHIDE_MULTI_SHADE(CElemBase pE, CView pV)
/////////////////////////////////////////////////////////////////77//////////
public void
CREATE_SINGLE_WIRE(CElemBase pE, CView pV, int n2, CPoint3D[,] vec2)
public void
MODIFY_SINGLE_WIRE(CElemBase pE, CView pV)
public void
DELETE_SINGLE_WIRE(CElemBase pE, CView pV)
public void
HIDE_SINGLE_WIRE(CElemBase pE, CView pV)
public void
UNHIDE_SINGLE_WIRE(CElemBase pE, CView pV)
/////////////////////////////////////////////////////////////////77//////////
public void
CREATE_MULTI_WIRE(CElemBase pE, CView pV, int[] segArray, CPoint3D[,]
vec2)
public void
MODIFY_MULTI_WIRE(CElemBase pE, CView pV)
public void
DELETE_MULTI_WIRE(CElemBase pE, CView pV)
public void
HIDE_MULTI_WIRE(CElemBase pE, CView pV)
public void
UNHIDE_MULTI_WIRE(CElemBase pE, CView pV)
Free View
Rotation Schemes
2012-February-02 |
1. Delta Rotation
/////////////////////////////////////////////////////////////////////////////
Use cursor's X Y delta. Location-transparent. Always 3D rotation.
2. Trackball
/////////////////////////////////////////////////////////////////////////////
If Pt.1 is within CircleA, initiate 3D rotation. If outside,
initiate 2D rotation. CircleA is 90% of the screen.
Once initiated, the rotation mode remains in effect until the mouse
button is released.
3. Trackball
/////////////////////////////////////////////////////////////////////////////
If Pt.1 is within CircleA, initiate 3D rotation. If outside, see if Vector1-2 goes through CircleB. If it does, 3D, else 2D.
CircleA is 50% of the screen. CircleB is the same as CircleA or smaller.
Once initiated, the rotation mode remains in effect until the mouse button is released.
CAD System Web Site - Computer Aided Design Software: Copyright
© 2010-2013 Makoto Honda. All Rights Reserved. |
|