Skip to main content



      Home
Home » Archived » GEF3D » Some refactoring, standalone draw3d viewers.
Some refactoring, standalone draw3d viewers. [message #3884] Tue, 02 June 2009 19:13 Go to next message
Eclipse UserFriend
Hi everyone,

just a quick pointer that I have refactored some gef3d and draw3d code.
I have created a new plugin called org.eclipse.draw3d.ui, which you
need to check out (from eclipse.org) in order to compile everything the
next time you update (if you are using SVN Head).

This was neccessary in order to support standalone draw3d viewers with
a working camera without duplicating lots of code. I will check in
another project containing the base classes and an example
implementation of such a viewer soon.

I hope I haven't broken anything - it seems to work fine on my system.

Miles: I will work on shapes after I finished the draw3d viewer. I will
add cones and cylinders first. Is there anything in particular that you
need?

Oh, and I have implemented the 3.5 Graphics methods, but will not
commit this until 3.5 is out. If you need patches against current SVN
for this, let me know.

Best regards
Kristian
Re: Some refactoring, standalone draw3d viewers. [message #4422 is a reply to message #3884] Tue, 02 June 2009 21:04 Go to previous messageGo to next message
Eclipse UserFriend
On 2009-06-02 16:13:02 -0700, Kristian Duske
<kristian.duske@fernuni-hagen.de> said:

> Hi everyone,
>
> just a quick pointer that I have refactored some gef3d and draw3d code.
> I have created a new plugin called org.eclipse.draw3d.ui, which you
> need to check out (from eclipse.org) in order to compile everything the
> next time you update (if you are using SVN Head).

Nice.. The whole IEditPart vs. IViewPart thing is really a relic at
this point. I find views to be much more suitable for a lot of stuff.

>
> This was neccessary in order to support standalone draw3d viewers with
> a working camera without duplicating lots of code. I will check in
> another project containing the base classes and an example
> implementation of such a viewer soon.

I just wrote one as well, but it's tied into all of the AGF pieces.
Found it really simple to do though. Unfortuntaly I don't have my CQs
for initial contributions in yet so I can't point to the code. But see
below..

For camera all I needed was to

CameraTool camera = new CameraTool();
getEditDomain().setActiveTool(camera);

> Miles: I will work on shapes after I finished the draw3d viewer. I will
> add cones and cylinders first. Is there anything in particular that you
> need?

Thanks for asking. :)

One thing that I'd like though I don't know if it would be useful for
anyone else is the ability to supply a 2D figure and then either rotate
it or

>
> Oh, and I have implemented the 3.5 Graphics methods, but will not
> commit this until 3.5 is out. If you need patches against current SVN
> for this, let me know.

The obvious hacks are working just fine.. I'm away for a week or so, btw..


package org.eclipse.amp.agf3d;



import org.eclipse.amp.agf.gef.EditPartListener;

import org.eclipse.amp.agf.gef.EditPartViewPart;

import org.eclipse.amp.axf.view.IModelPart;

import org.eclipse.gef.EditPartViewer;

import org.eclipse.gef.RootEditPart;

import org.eclipse.gef3d.preferences.ScenePreferenceListener;

import org.eclipse.gef3d.tools.CameraTool;

import org.eclipse.gef3d.ui.parts.GraphicalViewer3DImpl;

import org.eclipse.gef3d.ui.parts.IScene;

import org.eclipse.swt.widgets.Composite;



public class GEF3DViewPart extends EditPartViewPart {



/**

* The preference listener for this editor.

*/

protected ScenePreferenceListener sceneListener;



public void createPartControl(Composite parent) {

super.createPartControl(parent);

parent.addDisposeListener(((GraphicalViewer3DImpl)
viewer).getLightweightSystem3D());



if (viewer instanceof IScene) {

sceneListener = new ScenePreferenceListener((IScene) viewer);

sceneListener.start();

}

}



EditPartListener rootListener;



public void createModelListeners() {

if (viewer.getContents() instanceof IModelPart) {

((IModelPart) viewer.getContents()).createModelListeners();

}

}



protected void createZoomer(RootEditPart rootEditPart) {

CameraTool camera = new CameraTool();

getEditDomain().setActiveTool(camera);

}



protected EditPartViewer createViewer() {

return new GraphicalViewer3DImpl();

}



/**

* {@inheritDoc}

*

* @see org.eclipse.gef.ui.parts.GraphicalEditor#dispose()

*/

@Override

public void dispose() {



if (sceneListener != null) {

sceneListener.stop();

}



super.dispose();

}

}



[Note for below ModelViewPart can be ignored -- it does some AGF stuff
and extends ViewPart implements IPropertyChangeListener.]


/**
* <copyright>
*
* Copyright (c) 2009 Metascape, LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Metascape - Initial API and Implementation
*
* </copyright>
*
*/
package org.eclipse.amp.agf.gef;

import java.util.Collections;
import java.util.List;

import org.eclipse.amp.axf.view.IModelPart;
import org.eclipse.amp.axf.view.ModelViewPart;
import org.eclipse.draw2d.IFigure;
import org.eclipse.gef.DefaultEditDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.RootEditPart;
import org.eclipse.gef.editparts.ScalableFreeformRootEditPart;
import org.eclipse.gef.editparts.ZoomManager;
import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IWorkbenchPart;

public abstract class EditPartViewPart extends ModelViewPart {

private final class PropertySelectionListener implements
ISelectionChangedListener {
public void selectionChanged(SelectionChangedEvent event) {
if (!event.getSelection().isEmpty() && event.getSelection()
instanceof StructuredSelection) {
StructuredSelection sel = (StructuredSelection)
event.getSelection();

propertySheetPage.selectionChanged(EditPartViewPart.this, new
StructuredSelection(sel

.getFirstElement()));
}
}
}

private DefaultEditDomain editDomain;
protected EditPartViewer viewer;
private EditPartListener rootListener;
public static double[] ZOOM_LEVELS = { .125, .25, .5, .75, 1.0,
1.25, 1.5, 2.0, 2.5, 3, 4, 6, 8 };
private ZoomManager zoomer;
private PropertySelectionListener selectionListener;

public EditPartViewPart() {
super();
setEditDomain(new DefaultEditDomain(null));
}

public void createPartControl(Composite parent) {
super.createPartControl(parent);
viewer = createViewer();
viewer.createControl(parent);
getEditDomain().addViewer(viewer);
createSelectionListener(viewer);
}

protected void createSelectionListener(ISelectionProvider provider) {
super.createSelectionListener(provider);
selectionListener = new PropertySelectionListener();
provider.addSelectionChangedListener(selectionListener);
}

protected EditPartViewer createViewer() {
return new ScrollingGraphicalViewer();
}

public void setInput(IEditorInput input) {
super.setInput(input);
final ModelEditPartInput mInput = (ModelEditPartInput) input;
// setPartName(getName());
if (input != null) {
RootEditPart rootEditPart = mInput.getRootEditPart();
if (rootEditPart != null) {
viewer.setRootEditPart(rootEditPart);
createZoomer(rootEditPart);
}
viewer.setEditPartFactory(mInput.getFactory());
viewer.setContents(getModel());
} else {
// viewer.setContents(null);
}
}

protected void createZoomer(RootEditPart rootEditPart) {
if (rootEditPart instanceof ScalableFreeformRootEditPart) {
zoomer = ((ScalableFreeformRootEditPart)
rootEditPart).getZoomManager();
zoomer.setZoomLevels(ZOOM_LEVELS);

zoomer.setZoomLevelContributions(Collections.singletonList(Z oomManager.FIT_ALL));


}
}

public void createModelListeners() {
super.createModelListeners();
rootListener = new EditPartListener(viewer.getControl(),
getEditPart());
rootListener.setWaitForPaint(false);
addModelListener(rootListener);
if (viewer.getContents() instanceof IModelPart) {
((IModelPart) viewer.getContents()).createModelListeners();
}
viewer.getControl().addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
rootListener.endPainting();
}
});
}

public EditPart getEditPart() {
List children = viewer.getRootEditPart().getChildren();
if (children.size() > 0) {
return (EditPart) children.get(0);
}
return null;
}

@Override
public Object getAdapter(Class type) {
if (type == ISelectionProvider.class) {
return getViewer();
}
if (type == EditPartViewer.class) {
return getViewer();
}
// TODO -- this should really be the child..
if (type == EditPart.class && getViewer() != null) {
return getViewer().getRootEditPart();
}
if (type == IFigure.class && getViewer() != null) {
return ((GraphicalEditPart)
getViewer().getRootEditPart()).getFigure();
}
if (type == ZoomManager.class) {
return getZoomer();
}
return super.getAdapter(type);
}

public EditPartViewer getViewer() {
return viewer;
}

public EditPartListener getRootListener() {
return rootListener;
}

/**
* Sets the EditDomain for this EditorPart.
*
* @param ed
* the domain
*/
protected void setEditDomain(DefaultEditDomain ed) {
this.editDomain = ed;
}

public void selectionChanged(IWorkbenchPart part, ISelection selection) {
}

public void dispose() {
super.dispose();
removeSelectionListener(viewer);
((ISelectionProvider)
viewer).removeSelectionChangedListener(selectionListener);
}

/**
* Returns the edit domain.
*
* @return the edit domain
*/
protected DefaultEditDomain getEditDomain() {
return editDomain;
}

public ZoomManager getZoomer() {
return zoomer;
}

}
Re: Some refactoring, standalone draw3d viewers. [message #4492 is a reply to message #4422] Tue, 02 June 2009 21:13 Go to previous messageGo to next message
Eclipse UserFriend
>
>> Miles: I will work on shapes after I finished the draw3d viewer. I will
>> add cones and cylinders first. Is there anything in particular that you
>> need?
>
> Thanks for asking. :)
>
> One thing that I'd like though I don't know if it would be useful for
> anyone else is the ability to supply a 2D figure and then either rotate
> it or

I forgot to finish my sentance!

...just place it on an x, y or z oriented plane. Of course we already
have Z :) But this would allow the simple creation of "cutouts".

As far as actual shapes go, for now I'm just using the LGWL primitives
which works but as the render context isn't passed in and based on your
previous comments that won't be a good solution for future.

It seems that spheres are expensive in 3D graphics! Hemispheres would
be really useful as well and regular polyhedra.
Re: Some refactoring, standalone draw3d viewers. [message #4630 is a reply to message #3884] Wed, 03 June 2009 05:37 Go to previous messageGo to next message
Eclipse UserFriend
Hi Kristian,

On 2009-06-03 01:13:02 +0200, Kristian Duske
<kristian.duske@fernuni-hagen.de> said:
> just a quick pointer that I have refactored some gef3d and draw3d code.
> I have created a new plugin called org.eclipse.draw3d.ui, which you
> need to check out (from eclipse.org) in order to compile everything the
> next time you update (if you are using SVN Head).
>
> This was neccessary in order to support standalone draw3d viewers with
> a working camera without duplicating lots of code. I will check in
> another project containing the base classes and an example
> implementation of such a viewer soon.

I would expect a new plugin called org.eclipse.draw3d.examples for that
purpose? You could move my viewer part demo from the gef3 examples to
that new plugin (or remove it, if it is only a duplicate).

> Miles: I will work on shapes after I finished the draw3d viewer. I will
> add cones and cylinders first. Is there anything in particular that you
> need?

Hehe... Although I'm not Miles I would like to vote for spheres :-D

Cheers

Jens
Re: Some refactoring, standalone draw3d viewers. [message #4698 is a reply to message #4630] Wed, 03 June 2009 06:09 Go to previous message
Eclipse UserFriend
Hi,

>
> I would expect a new plugin called org.eclipse.draw3d.examples for that
> purpose? You could move my viewer part demo from the gef3 examples to
> that new plugin (or remove it, if it is only a duplicate).

No, the viewer base class should go into draw3d.ui I think. It's not an
example, but a base class that everyone can use to implement their
viewer.

> ehe... Although I'm not Miles I would like to vote for spheres :-D

Okay!

Kristian
Re: Some refactoring, standalone draw3d viewers. [message #561955 is a reply to message #3884] Tue, 02 June 2009 21:04 Go to previous message
Eclipse UserFriend
On 2009-06-02 16:13:02 -0700, Kristian Duske
<kristian.duske@fernuni-hagen.de> said:

> Hi everyone,
>
> just a quick pointer that I have refactored some gef3d and draw3d code.
> I have created a new plugin called org.eclipse.draw3d.ui, which you
> need to check out (from eclipse.org) in order to compile everything the
> next time you update (if you are using SVN Head).

Nice.. The whole IEditPart vs. IViewPart thing is really a relic at
this point. I find views to be much more suitable for a lot of stuff.

>
> This was neccessary in order to support standalone draw3d viewers with
> a working camera without duplicating lots of code. I will check in
> another project containing the base classes and an example
> implementation of such a viewer soon.

I just wrote one as well, but it's tied into all of the AGF pieces.
Found it really simple to do though. Unfortuntaly I don't have my CQs
for initial contributions in yet so I can't point to the code. But see
below..

For camera all I needed was to

CameraTool camera = new CameraTool();
getEditDomain().setActiveTool(camera);

> Miles: I will work on shapes after I finished the draw3d viewer. I will
> add cones and cylinders first. Is there anything in particular that you
> need?

Thanks for asking. :)

One thing that I'd like though I don't know if it would be useful for
anyone else is the ability to supply a 2D figure and then either rotate
it or

>
> Oh, and I have implemented the 3.5 Graphics methods, but will not
> commit this until 3.5 is out. If you need patches against current SVN
> for this, let me know.

The obvious hacks are working just fine.. I'm away for a week or so, btw..


package org.eclipse.amp.agf3d;



import org.eclipse.amp.agf.gef.EditPartListener;

import org.eclipse.amp.agf.gef.EditPartViewPart;

import org.eclipse.amp.axf.view.IModelPart;

import org.eclipse.gef.EditPartViewer;

import org.eclipse.gef.RootEditPart;

import org.eclipse.gef3d.preferences.ScenePreferenceListener;

import org.eclipse.gef3d.tools.CameraTool;

import org.eclipse.gef3d.ui.parts.GraphicalViewer3DImpl;

import org.eclipse.gef3d.ui.parts.IScene;

import org.eclipse.swt.widgets.Composite;



public class GEF3DViewPart extends EditPartViewPart {



/**

* The preference listener for this editor.

*/

protected ScenePreferenceListener sceneListener;



public void createPartControl(Composite parent) {

super.createPartControl(parent);

parent.addDisposeListener(((GraphicalViewer3DImpl)
viewer).getLightweightSystem3D());



if (viewer instanceof IScene) {

sceneListener = new ScenePreferenceListener((IScene) viewer);

sceneListener.start();

}

}



EditPartListener rootListener;



public void createModelListeners() {

if (viewer.getContents() instanceof IModelPart) {

((IModelPart) viewer.getContents()).createModelListeners();

}

}



protected void createZoomer(RootEditPart rootEditPart) {

CameraTool camera = new CameraTool();

getEditDomain().setActiveTool(camera);

}



protected EditPartViewer createViewer() {

return new GraphicalViewer3DImpl();

}



/**

* {@inheritDoc}

*

* @see org.eclipse.gef.ui.parts.GraphicalEditor#dispose()

*/

@Override

public void dispose() {



if (sceneListener != null) {

sceneListener.stop();

}



super.dispose();

}

}



[Note for below ModelViewPart can be ignored -- it does some AGF stuff
and extends ViewPart implements IPropertyChangeListener.]


/**
* <copyright>
*
* Copyright (c) 2009 Metascape, LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Metascape - Initial API and Implementation
*
* </copyright>
*
*/
package org.eclipse.amp.agf.gef;

import java.util.Collections;
import java.util.List;

import org.eclipse.amp.axf.view.IModelPart;
import org.eclipse.amp.axf.view.ModelViewPart;
import org.eclipse.draw2d.IFigure;
import org.eclipse.gef.DefaultEditDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.RootEditPart;
import org.eclipse.gef.editparts.ScalableFreeformRootEditPart;
import org.eclipse.gef.editparts.ZoomManager;
import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IWorkbenchPart;

public abstract class EditPartViewPart extends ModelViewPart {

private final class PropertySelectionListener implements
ISelectionChangedListener {
public void selectionChanged(SelectionChangedEvent event) {
if (!event.getSelection().isEmpty() && event.getSelection()
instanceof StructuredSelection) {
StructuredSelection sel = (StructuredSelection)
event.getSelection();

propertySheetPage.selectionChanged(EditPartViewPart.this, new
StructuredSelection(sel

.getFirstElement()));
}
}
}

private DefaultEditDomain editDomain;
protected EditPartViewer viewer;
private EditPartListener rootListener;
public static double[] ZOOM_LEVELS = { .125, .25, .5, .75, 1.0,
1.25, 1.5, 2.0, 2.5, 3, 4, 6, 8 };
private ZoomManager zoomer;
private PropertySelectionListener selectionListener;

public EditPartViewPart() {
super();
setEditDomain(new DefaultEditDomain(null));
}

public void createPartControl(Composite parent) {
super.createPartControl(parent);
viewer = createViewer();
viewer.createControl(parent);
getEditDomain().addViewer(viewer);
createSelectionListener(viewer);
}

protected void createSelectionListener(ISelectionProvider provider) {
super.createSelectionListener(provider);
selectionListener = new PropertySelectionListener();
provider.addSelectionChangedListener(selectionListener);
}

protected EditPartViewer createViewer() {
return new ScrollingGraphicalViewer();
}

public void setInput(IEditorInput input) {
super.setInput(input);
final ModelEditPartInput mInput = (ModelEditPartInput) input;
// setPartName(getName());
if (input != null) {
RootEditPart rootEditPart = mInput.getRootEditPart();
if (rootEditPart != null) {
viewer.setRootEditPart(rootEditPart);
createZoomer(rootEditPart);
}
viewer.setEditPartFactory(mInput.getFactory());
viewer.setContents(getModel());
} else {
// viewer.setContents(null);
}
}

protected void createZoomer(RootEditPart rootEditPart) {
if (rootEditPart instanceof ScalableFreeformRootEditPart) {
zoomer = ((ScalableFreeformRootEditPart)
rootEditPart).getZoomManager();
zoomer.setZoomLevels(ZOOM_LEVELS);

zoomer.setZoomLevelContributions(Collections.singletonList(Z oomManager.FIT_ALL));


}
}

public void createModelListeners() {
super.createModelListeners();
rootListener = new EditPartListener(viewer.getControl(),
getEditPart());
rootListener.setWaitForPaint(false);
addModelListener(rootListener);
if (viewer.getContents() instanceof IModelPart) {
((IModelPart) viewer.getContents()).createModelListeners();
}
viewer.getControl().addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
rootListener.endPainting();
}
});
}

public EditPart getEditPart() {
List children = viewer.getRootEditPart().getChildren();
if (children.size() > 0) {
return (EditPart) children.get(0);
}
return null;
}

@Override
public Object getAdapter(Class type) {
if (type == ISelectionProvider.class) {
return getViewer();
}
if (type == EditPartViewer.class) {
return getViewer();
}
// TODO -- this should really be the child..
if (type == EditPart.class && getViewer() != null) {
return getViewer().getRootEditPart();
}
if (type == IFigure.class && getViewer() != null) {
return ((GraphicalEditPart)
getViewer().getRootEditPart()).getFigure();
}
if (type == ZoomManager.class) {
return getZoomer();
}
return super.getAdapter(type);
}

public EditPartViewer getViewer() {
return viewer;
}

public EditPartListener getRootListener() {
return rootListener;
}

/**
* Sets the EditDomain for this EditorPart.
*
* @param ed
* the domain
*/
protected void setEditDomain(DefaultEditDomain ed) {
this.editDomain = ed;
}

public void selectionChanged(IWorkbenchPart part, ISelection selection) {
}

public void dispose() {
super.dispose();
removeSelectionListener(viewer);
((ISelectionProvider)
viewer).removeSelectionChangedListener(selectionListener);
}

/**
* Returns the edit domain.
*
* @return the edit domain
*/
protected DefaultEditDomain getEditDomain() {
return editDomain;
}

public ZoomManager getZoomer() {
return zoomer;
}

}
Re: Some refactoring, standalone draw3d viewers. [message #561972 is a reply to message #4422] Tue, 02 June 2009 21:13 Go to previous message
Eclipse UserFriend
>
>> Miles: I will work on shapes after I finished the draw3d viewer. I will
>> add cones and cylinders first. Is there anything in particular that you
>> need?
>
> Thanks for asking. :)
>
> One thing that I'd like though I don't know if it would be useful for
> anyone else is the ability to supply a 2D figure and then either rotate
> it or

I forgot to finish my sentance!

...just place it on an x, y or z oriented plane. Of course we already
have Z :) But this would allow the simple creation of "cutouts".

As far as actual shapes go, for now I'm just using the LGWL primitives
which works but as the render context isn't passed in and based on your
previous comments that won't be a good solution for future.

It seems that spheres are expensive in 3D graphics! Hemispheres would
be really useful as well and regular polyhedra.
Re: Some refactoring, standalone draw3d viewers. [message #562010 is a reply to message #3884] Wed, 03 June 2009 05:37 Go to previous message
Eclipse UserFriend
Hi Kristian,

On 2009-06-03 01:13:02 +0200, Kristian Duske
<kristian.duske@fernuni-hagen.de> said:
> just a quick pointer that I have refactored some gef3d and draw3d code.
> I have created a new plugin called org.eclipse.draw3d.ui, which you
> need to check out (from eclipse.org) in order to compile everything the
> next time you update (if you are using SVN Head).
>
> This was neccessary in order to support standalone draw3d viewers with
> a working camera without duplicating lots of code. I will check in
> another project containing the base classes and an example
> implementation of such a viewer soon.

I would expect a new plugin called org.eclipse.draw3d.examples for that
purpose? You could move my viewer part demo from the gef3 examples to
that new plugin (or remove it, if it is only a duplicate).

> Miles: I will work on shapes after I finished the draw3d viewer. I will
> add cones and cylinders first. Is there anything in particular that you
> need?

Hehe... Although I'm not Miles I would like to vote for spheres :-D

Cheers

Jens
Re: Some refactoring, standalone draw3d viewers. [message #562031 is a reply to message #4630] Wed, 03 June 2009 06:09 Go to previous message
Eclipse UserFriend
Hi,

>
> I would expect a new plugin called org.eclipse.draw3d.examples for that
> purpose? You could move my viewer part demo from the gef3 examples to
> that new plugin (or remove it, if it is only a duplicate).

No, the viewer base class should go into draw3d.ui I think. It's not an
example, but a base class that everyone can use to implement their
viewer.

> ehe... Although I'm not Miles I would like to vote for spheres :-D

Okay!

Kristian
Previous Topic:Lighting
Next Topic:interpolated animation
Goto Forum:
  


Current Time: Tue Jul 01 07:50:19 EDT 2025

Powered by FUDForum. Page generated in 0.03737 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top