Transparent GeometryModel3D - c#

I need to create a transparent GeometryModel3D.
Like this:
I tried this code:
var m = new Model3DGroup();
var panelsGeometry = MyMeshGeometry3D;
Brush br = new SolidColorBrush(Colors.Red);
br.Opacity = 0.5;
m.Children.Add(new GeometryModel3D(panelsGeometry, new DiffuseMaterial(br)) { BackMaterial= new DiffuseMaterial(br) });
But as a result I get this:
What am I doing wrong? Thanks.

You could use a transparent image with an ImageBrush, one pixel would be enough but you will need to set TextureCoordinates on the mesh object.

You need to use TextureCoordinates and you wil have to order the sides to be drawn from back to front so they blend correctly. WPF doesn´t do this.
See this article

Make sure your box mesh geometry contains 24 points. If your box contains the minimum number of points (8), then the behind faces won't be rendered.
For example, see here.
You can download the Normals3D.zip and change the brush opacity of the full mesh boxes to get the desired effect.

Related

How do you replace a mask with a specific color?

I am using the following code snippet to remove the background from an image.
int[] bgColors = {203,255,240}
ImageMagick.MagickImage image = new ImageMagick.MagickImage("input.jpg")
ImageMagick.MagickImage combineMask= new ImageMagick.MagickImage("mask.jpg")
combineMask.Blur(7, 30);
image.Composite(combineMask, ImageMagick.CompositeOperator.CopyAlpha);
image.Settings.BackgroundColor = new ImageMagick.MagickColor(bgColors[0], bgColors[1], bgColors[2]);
image.Alpha(ImageMagick.AlphaOption.Remove);
It takes the MagickImage image and the MagickImage combineMask and outputs a combined image as linked below.
Original + Mask = Final
Previously, I never needed anything other than a plain white background (which this provides). Now, I would like to be able to set the color of the background. I started by passing a non (255,255,255) set of colors to the settings to image.Settings.BackgroundColor. This did not accomplish anything. I've been trying to investigate the MagickImage library (through their github, they don't really have very complete documentation), but it has remained inscrutable.
How could I get image.Alpha(ImageMagick.AlphaOption.Remove); to replace the removed section with the background color (or a passed color), or otherwise change the color of the background?
Solution
I've figured out a Solution that takes me 90% of the way there.
int[] bgColors = {203,255,240}
ImageMagick.MagickImage image = new ImageMagick.MagickImage("input.jpg")
ImageMagick.MagickImage combineMask= new ImageMagick.MagickImage("mask.jpg")
combineMask.ColorFuzz = new ImageMagick.Percentage(5);
combineMask.Transparent(ImageMagick.MagickColor.FromRgb(255, 255, 255));
combineMask.Opaque(ImageMagick.MagickColor.FromRgb((byte)0, (byte)0, (byte)0),
ImageMagick.MagickColor.FromRgb((byte)bgColors[0], (byte)bgColors[1], (byte)bgColors[2]));
image.Composite(combineMask, ImageMagick.CompositeOperator.Over);
Instead of using the Black/White mask and grabbing alpha channels, I am converting the white part of the mask to transparent, then converting the black part of the mask to the colors contained in the bgColors.
Now, because the formerly white area is now transparent, I cannot blur the image in order to create a smooth transition between mask and picture, which I still need to fix.

Detecting presence of "Drawn text" under the mouse?

and thanks for taking a peek at my conundrum.
I am trying to write a series of strings to an image as overlays, then later be able to come back and move, or delete one of them selectively using WPF framework...
I've been looking into the FindVisualChildren function, but for the moment cant make heads or tails of how to detect the proximity to the mouse (for selectivity), or actually detect one of my created strings (Perhaps I should be making them dynamic 'Label' elements...????)
Insomnia sucks, and my brains are turning to mush.
TIA for any advice!
Okay, sorry for the lack of sample code, been a long night... well two nights actually (See earlier comment about insomnia)
public void WriteTextToImage(Point position)
{
ImageSource bitmapSource = imgFrame.Source;
var vis = new DrawingVisual();
using (DrawingContext drawingContext = vis.RenderOpen())
{
// Set the pen color... Why is this called a brush if it's for
// writing? perhaps I should overload it and call it crayon?
SolidColorBrush brush = new SolidColorBrush((Color)cpColor.SelectedColor);
drawingContext.DrawImage(bitmapSource, new Rect(0, 0, imgFrame.Source.Width, imgFrame.Source.Height));
//Write some pretty words, (actually print some general stuff)
drawingContext.DrawText(new FormattedText(tbCurrentLabel.Text, CultureInfo.InvariantCulture, FlowDirection.LeftToRight, new Typeface("Arial"), slFontSize.Value, brush),position);
}
//Slap this puppy to the screen
var image = new DrawingImage(vis.Drawing);
//Iterate the label text to the next digit or value
IterateLabel();
}
Basically what will happen is the user will click the screen in several places to make marks on the image for printing, but I want to include support to move those marks, and delete them as needed.
I hope this explains what I am trying to accomplish a little better.
Thanks again!
Excellent! thanks NineBerry, I figured it was going to be something like that. I was originally thinking a label, but the textblock worked perfectly.
Here's the updated code showing how I am getting it done now.
public void WriteTextToImage(Point position)
{
SolidColorBrush brush = new SolidColorBrush((Color)cpColor.SelectedColor);
//Get something to write on (not an old receipt...)
TextBlock textBlock = new TextBlock();
//Say something useful... well something atleast...
textBlock.Text = tbCurrentLabel.Text;
textBlock.FontSize = slFontSize.Value;
textBlock.Foreground = brush;
Canvas.SetLeft(textBlock, position.X);
Canvas.SetTop(textBlock, position.Y);
canvas.Children.Add(textBlock);
//Need to update the canvas, was not seeing children before doing this.
canvas.UpdateLayout();
//Iterate the label text
IterateLabel();
}`

Issues with making a 3D model faces semi-transparent using HelixToolkit

I am trying to display the 3D model depicted below using HelixToolkit. (The following snapshot's taken from SolidWorks.)
I set the brush color of the DiffuseMaterial used as Material and BackMaterial of my GeometryModel3D to a tranparent color.
Model3DGroup faceVisualEntity = ModelFaces.First(modelFace => modelFace.Content.GetName() == faceName).Content as Model3DGroup;
// Breaking the 3D-model down to the constituting mesh..
//
foreach (var child in faceVisualEntity.Children)
{
if (child is GeometryModel3D)
{
GeometryModel3D body = child as GeometryModel3D;
body.Material = new DiffuseMaterial(new SolidColorBrush("#40FF0000"));
body.BackMaterial = new DiffuseMaterial(new SolidColorBrush("#40FF0000"));
}
}
However, what I can see in HelixViewport3D is like below.
While the sides of the box seem to be transparent, I wonder why the pipes inside the box cannot be seen. I also changed the color of the pipe walls to an opaque value, but cannot see them yet.
The fact is that using the transparency feature of the HelixToolkit is not achieved by changing the alpha channel of the model faces material only. Actually, there is an example in the HelixToolkit code showing that a SortingVisual3D is required to support transparency for the model. So, I first added an instance of SortingVisual3D to the HelixViewport3D and then added the Visual3D objects, such as ModelVisual3D, LinesVisual3D, etc., to it. As a result, what I can see now is like below.

XNA BlendState with SpriteBatch

We are needing a BlendState to act as the following:
Transparent PNGs are drawn as expected, with anything behind them preserved
We use Color.White to draw a PNG as-is
We will change the alpha channel of the color to change the "opacity" of the texture
To get this effect, BlendState.AlphaBlend is close, but draws white as the transparent part if we set alpha to 100 or any number other than 255.
So we attempted this:
_blendState = new BlendState();
_blendState.AlphaSourceBlend = Blend.SourceAlpha;
_blendState.AlphaDestinationBlend = Blend.InverseSourceAlpha;
_blendState.ColorSourceBlend = Blend.SourceAlpha;
_blendState.ColorDestinationBlend = Blend.InverseSourceAlpha;
This works, except we now get undesired effects if two PNGs are on top of one another. Basically we get some weird lines where it looks like pixel data is being added (or something).
Example:
Effectively, BlendState.AlphaBlend is this:
_blendState = new BlendState();
_blendState.AlphaSourceBlend = Blend.SourceAlpha;
_blendState.AlphaDestinationBlend = Blend.InverseSourceAlpha;
_blendState.ColorSourceBlend = Blend.One;
_blendState.ColorDestinationBlend = Blend.InverseSourceAlpha;
Image looks better than above:
But then alpha doesn't work, using 100 as alpha would replace the background with white.
What BlendState should we use to get our desired effect from SpriteBatch? We are OK to use a different color such as Color.Black there is another way to get it to work.
*PS - another nice feature would be if we could use Color.Red to "tint" a texture, but we want it to work in general first.
Try setting premultipliedAlpha to false for those .png's in your Content Project.
Unfortunately, I don't know how to resolve this issue when using Texture2d.FromStream().

Draw a Grid over a Picturebox in c#

I am trying to make a tool in c# which allows the user to put a grid on the screen on a picturebox. At the moment i don't know how to do this, so when a button is clicked, the picturebox comes up with a grid. It needs to be a grid which is spaced out enough that users can find out locations of objects on the picture in the picturebox. Help with what code i can use to do this would be very helpful as i was going to use ControlPaint.DrawGrid but not sure of the values i need to put in it to get my desired effect?
Thanks
Form the Documentation od controlpaint.Drawgrid,
I suppose you need to decide on the cell size in x- amd y-direction and pass this as a size parameter to Drawgrid:
public static void DrawGrid(
Graphics graphics,
Rectangle area,
Size pixelsBetweenDots,
Color backColor
)
for example, a 100*200 pixels square grid would be generated by
setting graphcis to the context you want to draw upon,
Setting area to the top left right and bottom parameters of your image
setting size.x to 100 and size.y to 200
setting color to any color you like.
Update
Something like this should do.
Rectangle myRect = new System.drawings.Rectangle();
myRect.Location := new System.Drawing.Point(0,0);
myRect.Height = 50;
myRect.Width = 50;
Drawgrid(FromImage(yourImage), mygrid , yourImage.Size, System.Drawing.Color.Black);
Disclaimer: i don't develope in c#, so above code is not tested for anything. I just picked stuff from the documentation (msdn).

Categories