¿Por qué estoy re-publicando algunas entradas?

Habrás observado que algunas entradas han sido re-publicadas con la fecha de hoy. El motivo es que he dado de alta este blog en la lista de blogs técnicos de www.codeproject.com. Como éste consume artículos recientes únicamente, algunas entradas que me parecían de utilidad no iban a ser consumidas por el robot de la página.

Por eso estoy re-publicandolas, para que codeproject se entere.

Siento las molestias.

Localization of .Net applications

These last days, I had the change to mess up with the Localization infrastructure inside Visual Studio 2008. I must realize it´s the first time I seriously get into this issue, and I´m impressed with the work done on it.
When one needs to give an application multi-language support, the first temptation (as old-time programmers) is to build up some sort of tables with strings, each one for each language. That´s more or less what the Localization system will do, but with the following extra features:
A comfortable visual editor
We have a comfortable visual editor to manage the string tables, like this one, giving you the chance to set comments to each entry.
55
Culture infrastructure-ready
The system offers automatic integration with the Culture infrastructure of each application. To get more info about this, check:
  • System.Threading.Thread.CurrentThread.CurrentCulture
  • System.Threading.Thread.CurrentThread.CurrentUICulture
This gives you automatic support for different numbering and date formats, etc.
Integrated with the Visual Studio Designer
To start localizing, you just have to open the design view of a form or control and set the Localizable property of any form or control to True to generate the default resource (.resx) file. From then, each time you 51select a new language in the combo (and change any property), a newer resX file is generated to reflect the change. Of course, all this files are perfectly managed by the Solution Explorer as a part of the form or the control.
Once a form is localizable, each time we change the current language, the designer automatically updates the design view to show the appearance of the form or control in that language. ResX files are also maintained automatically.
Localization of the entire looking (not only texts)
You can make specific versions of each control or user interface for each language, including control positions, dimensions, colors, anything...
This is specially relevant because many times is not enough with just replacing texts. The translation of a text may have a remarkable different length in other languages. In this case we would have to resize the label containing the string, and maybe relocate other controls in the form, as in the following picture, where you can see two version of the same form, for two different languages.
52
Note: Text strings are saved directly in the resx files accompanying the Form1.cs class, but other properties, like dimensiones, locations, etc, are saved in other place. When you compile your solution, in the output directory you will find additional folders with culture-specific names, like “en-US”, etc. This folders will contain additional DLLs created automatically by VisualStudio, one for each localizable assembly. Inside this DLLs, you will find resources defining the appearance of the form´s controls.
Additional String Tables
We have talked about resource files handled by the Designer to reflect the appearance changes of forms for different languages but, what happens with the message shown in a MessageBox? This is not something we can manage in a design view.
A solution is to insert additional .resx files to the project. We can make them “embedded resources” and easily access them with the ResourceManager class directly, although I must tell you this is not the best solution (see next chapter). Of course, there´s no designer to handle this tables, so they will have to be maintained manually (using the visual editor).
To include a complete collection of additional string tables, you can start with the default resx file (for the default language). Give it any name you like, for example: “LocalizedStrings.resx” (just click your project with the right button, and select “Add New item”, and then “Resource File” as the item type). Afterwards, you can add any other language version for that file, using the same name with the culture-specific string representation before the extension. Some examples:
  • LocalizedStrings.en-US.resx
  • LocalizedStrings.es-ES.resx
  • LocalizedStrings.fr-FR.resx
Strongly-typed access to string tables
This is also a very important feature, because once you have your string table up and running, you need to get access to it from your code. You can do so directly through the ResourceManager.GetString() method, but this is definitely not a good idea. Mostly because you will have to give it the name of the entry you are looking for, in the form of a simple "string”.
This means that you will have no Intellisense support (you will have to look the name of the properties in the table by yourself), and if any property name is changed later, there will be no compiling warning or error. This means that if you are not extremely careful for the rest of your application´s life, you won´t notice the mistake until runtime, and this is extremely bug-prone.
The solution is to make a strongly-typed class, which includes code properties to access each entry in the table. Of course, it would be a non sense if we had to make them manually (it would be the same as accessing though the ResourceManager class). Thankfully VisualStudio includes a tool to take care of such task: the ResXFileCodeGenerator. To make VisualStudio invoke this tool, you will have to put it´s name (“ResXFileCodeGenerator”, without quotes) in the Custom Tool property of the default resx file. This is important: IN THE DEFAULT resx file. This means that, if you have LocalizedStrings.resx (with the default language, spanish for example), and LocalizedStrings.en-US.resx, you have to set the custom tool to the first one.
53
When you do so, a new “.cs” file will be generated for you (below the resx file) containing the strongly-typed class. Though the maintenance of this class is automatic, you can force a refresh anytime you want by clicking the resx file with the right button and selecting “Run custom tool”.
From now, you can access your strint table texts with Intellisensed, strongly-typed, in-code properteties like:
“text = LocalizedStrings.strWarningCaption”
APPENDIX A: Making an automatically-generated, strongly-typed class to be PUBLIC
By default, strongly-typed classes generated with the ResXFileCodeGenerator tool are INTERNAL. This means that they will only be accessible inside your assembly.
To make one of this classes public, you cannot just change its code as it will be re-generated by the tool on next rebuild. You have to change the custom tool, selecting the PublicResXFileCodeGenerator instead of the previous one. It will make them public for you.
You can also do this “double-clicking” your string table (to enter the visual editor view), and selecting the PUBLIC modifier in the upper part of the screen (this actually changes the custom tool as explained above).
Well, it´s been long, but hope it helps someone. However, this is my first approach to Localization and therefore, for sure there will be people with deeper knowledge on this issue. Please feel free to complete (or correct) this tutorial with comments and suggestions.
Thanks!

Parallel computing and processor affinity. Never underestimate the Windows Vista Scheduler

[Traducido al Español por Matías Cordero. Puedes leer la versión en Castellano aqui]
Everyone knows that parallelization is a hard but important issue, as it seems that it´s not affordable anymore to increase CPU clock speeds. The future is multi-core! So you should start getting familiar with System.Threading a.s.a.p. ;)
Determine the appropriate balance
When one identifies a parallelizable task, it´s always hard to find the appropriate balance for parallelization. Is it better to open more threads or is it better to give more work to each thread? The answer to that question of course depends on many things, and remarkably on the nature of the task each thread will handle.
It is important to guess the amount of time that task will idle in each thread. If it´s an intensive task, then better start less threads with more work each. If it´s just the opposite (a task that will frequently idle waiting for something -IO, graphics, whatever-), then better open more threads with less work, as they will scheduled through the physical cores of your machine when one is idling. Of course, never open less threads than your machines physical cores!
What´s the objective? The same as in hotels… 100% occupancy.
An easy way to determine the nature of our task is to let it run on a single CPU, and see the Task Manager CPU usage history graph. This will give you an idea of the CPU usage your process made. You will ask now how to force your application to run in a specific CPU. The answer is Processor Affinity (see below).


To loose, or not to loose control. That´s the question…
When one starts dealing with parallelization, the first idea is to split processes through the CPUs oneself. Why not? If you have 10.000 operations, then open four threads with 25.000 operations each. First for CPU0, second for CPU1 and so on… I´d feel very comfortable with this idea. Neat and clean, and everything under control, right? Well, it´s not always that simple.
In an ideal world, a single task that is not going to be parallelized anymore and that lives alone (not with the dozens of neighbors a process has in a modern OS), is better handled by a single CPU, as this will increment cache hits and eliminates any thread switching infrastructure overhead. But in real life, processes are interrupted by OS operations, IO, other processes and many other things. A multi-core machine is perfect for handling all that interruptions, as it can spread them all through the existing cores, but if we all start fixing our applications to specific CPUs, the capacity of the OS to avoid locks and waits is heavily reduced.
As this great article explains, most of the times, it is much better to rely onto the Operating System so it can put each thread wherever he wants. However, we´ll see some results regarding this decision later.


Processor affinity of a process

In Windows, you can force a process to run in a specific CPU just using the Task Manager (right click your process and select “Set Affinity”) or programmatically using the System.Diagnostics namespace. The following line will change current process affinity to CPU 1:
System.Diagnostics.Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)1;
The ProcessorAffinity property is a bit mask variable. So, the values are:
Value Allowed processors
0 (0000) Not allowed (that would mean use no processors)
1 (0001) Use processor 1
2 (0010) Use processor 2
3 (0011) Use both processors 1 and 2
4 (0100) Use processor 3
5 (0101) Use both processors 1 and 3
6 (0110) Use both processors 2 and 3
7 (0111) Use processors 1,2 and 3
8 (1000) Use processor 4
and so on…  
Please note that this will change the affinity of the current process (your entire application), not of the current thread. Any thread opened from this process will inherit the same affinity.

Processor affinity of a thread

A first requirement in order to control how your threads are distributed through CPUs is to be able to set a thread´s affinity (not a process). There is an interesting post about this issue here, where Tamir Khason explains the whole thing. To change a thread´s affinity we must use the System.Diagnostics.ProcessThread class (ProcessAffinity property). The problem comes when one tries to find out which thread is the one we are looking for, in the list of the current process´ threads.

First Approach - Deprecated

We get the ProcessThread instance with the following code:
ProcessThread t = Process.GetCurrentProcess().Threads.OfType<ProcessThread>().Single(pt => pt.Id == AppDomain.GetCurrentThreadId());
t.ProcessorAffinity = (IntPtr)(int)cpuID;
The problem with this approach is that the method GetCurrentThreadId is deprecated, so better you don´t use it.

Second approach – Not valid

You could be tempted to use the ManagedThreadID to search inside the Threads collection of your process. Don´t do it. ProcessThread.ID has nothing to do with the ManagedThreadID property, they represent different things. A guy says here that ManagedThreadID is in fact the offset inside the ProcessThread collection, but I didn´t investigate any further, and I wouldn´t advise you to do so unless you verify this information

Third approach – Valid but unmanaged

The third approach will “dllimport” kernel32.dll and use some of it´s functions. This method is tested and works correctly. Here we go:
[DllImport("kernel32.dll")] 
static extern IntPtr GetCurrentThread();
[DllImport("kernel32.dll")] 
static extern IntPtr SetThreadAffinityMask(IntPtr hThread, IntPtr dwThreadAffinityMask);
SetThreadAffinityMask(GetCurrentThread(), new IntPtr(1 << (int)cpuID));
A curious note:
If you are programming for the XBox360 with the XNA Game Studio 3.0, you have a Thread.SetProcessorAffinity method ready for you, without all the garbage above. This is just because the XBox specially needs to take advantage of its cores to give a decent performance. I don´t know if the presence of this method is due to a worse performance of the XBox Scheduler than in Vista… may be. However you can read further here.

 

The Tests

Task: Generation of three 2D tables of information as a result of a geometric test in a 3D scene, involving 975.065 collision tests (ray-mesh) each
Hardware: Dell XPS 630 QuadCore
Monitoring software: Process Explorer

PART 1 (multithreading disabled). Impact of processor affinity

Test 1:
  • Number of threads: 1 (main thread)
  • Processor affinity: CPU 1
  • Total time: 2 min 57.11 secs
image
With processor affinity enabled to CPU 1, all the work is obviously handled by this CPU. The two peaks you can appreciate in the graph are due to a IO operation (saving data to disk) and clearly demarcate the generation of each table of data. In this test we can clearly appreciate that our task is very intensive and constant, as keeps the processor at a 100% usage almost all the time.
Test 2:
  • Number of threads: 1 (main thread)
  • Processor affinity: None (any processor)
  • Total Time: 2 min 29.45 secs
image
Most of the work was handled by CPU 2 but the rest of cores also worked on the process (checked in Process Explorer that all the green lines belonged to the process being measured). It is clear that forcing the thread to work in CPU 1 only introduced locks and waiting periods probably due to interruptions coming from other programs that needed CPU 1 too.
Winner of part 1 ………  Windows Scheduler !

PART 2 (multithreading enabled 1)

Test 1:
  • Number of threads: 2 (main thread + 1 calculation thread)
  • Processor affinity:
    • Main thread: Any
    • Calculation thread: CPU 1
  • Total time: 2 min 18.14 secs
image
The results we are getting here are quite logical. The main change in this test is that we are separating the calculation from UI update and IO saving to disk. You can appreciate the low peaks in the first graph and their equivalent in cores 2 and 3 (where the saving operation is placed). It is very interesting to note that separating the saving operation to different cores doesn´t save any time, because we wait for it to complete before continuing with the next table of data. That´s why now the low peaks in the first graph are much more noticeable. We have moved some computing from one core to another, but not parallelized anything.
However, we get a small performance improvement, mostly because now the UI update (which involves some Bitmap manipulation) is now done at cores 2 and 3
Test 2:
  • Number of threads: 2 (Main thread + 1 calculation thread)
  • Processor affinity: None
  • Total time: 2 min 14.86 secs
image
This time, we can again appreciate that work has been scattered through all cores, with a more remarkable presence of CPU 2. Again, the Windows scheduler wins the race.
Winner of part 2 ………  Windows Scheduler !

PART 3 (multithreading enabled 2)  

Test 1:
  • Number of threads: 3 (main thread + 2 calculation threads)
  • Processor affinity:
    • Main thread: Any
    • Calculation threads: CPUs 1 and 2
  • Total time: 1 min 18.66 secs
image
We start to see a big performance improvement here. Twice the computing power, almost twice faster. That seems quite realistic.
Test 2:
  • Number of threads: 3 (main thread + 2 calculation threads)
  • Processor affinity: None
  • Total time: 1 min 16.59 secs
image
Another win for the Windows Scheduler. Obviously when the total time gets shorter, the differences too, but the OS still wins.
Winner of part 3 ………  Windows Scheduler !

PART 4 (multithreading enabled 3)
Test 1:
  • Number of threads: 5 (main thread + 4 calculation thread)
  • Processor affinity:
    • Main thread: Any
    • Calculation threads: CPUs 1, 2, 3 and 4
  • Total time: 41.76 secs
image
Now comes the huge performance improvement. With 4 calculating threads, the total time gets reduced to 41 secs!. Let´s see how the OS performs with 5 threads.
Test 2:
  • Number of threads: 5 (main thread + 4 calculation thread)
  • Processor affinity: None
  • Total time: 42.05 secs
image
Wow… That was too close! This time we must mark the OS as looser.
Winner of part 4 ………  Processor Affinity! (it was close)

PART 5 (multithreading enabled 4)
Test 1:
  • Number of threads: 9 (main thread + 8 calculation threads)
  • Processor affinity:
    • Main thread: Any
    • Calculation threads 1..4: CPUs 1..4
    • Calculation threads 5..8: CPUs 1..4
  • Total time: 41.07 secs
 image
Test 2:
  • Number of threads: 9 (Main thread + 8 calculation threads)
  • Processor affinity: None
  • Total time: 38.24 secs
image
Wow… this is my boy! 38 secs !!!
However, this are expected results. If you set more threads than physical cores, it is obvious that some thread scheduling should have to be done. Forcing threads to work on a certain CPU just brings down parallelization. As you can see we get almost no benefit when using 8 calculation threads instead of 4 (if affinity is enabled). So it´s clear that giving some freedom to Windows here, just to do its job, is by far the best option.
Winner of part 5 ………  Windows Scheduler !
 

Results

 graph

 

Test Vista Scheduler Processor Affinity
Part 1 149.45 secs 177.11 secs
Part 2 134.86 secs 138.14 secs
Part 3 76.59 secs 78.66 secs
Part 4 42.05 secs 41.76 secs
Part 5 38.24 secs 41.07 secs

So, what´s the optimal number of threads for my task?

Does this tendency (the more threads, the higher performance) continues forever? The answer is, obviously, no.
In an ideal, 100% intensive and constant task, the optimal number of threads would be the number of physical cores, but in real life, such an intensive task is very difficult to find. Almost every computation algorithm will have idle times, waiting for a memory paging operation or whatever. So, the number of threads that will give you top performance will depend on the intensiveness and constancy of your application.
I have measured some additional timings (for the OS scheduler version only):
        • 16 threads –> 37.89 secs.
        • 18 threads –> 37.44 secs.
        • 24 threads –> 38.03 secs.
So, for this task the tendency seems to break at 18 threads. You will have to make your own tests to find the optimal number of threads for your algorithm. However, we have proven that even in such an intensive task as this one, the optimal number of threads seems to be around 18 for a quad core machine, that means more than 4 times the number of physical cores!

 

Conclusions

1.- The Windows Scheduler does a GREAT job (specially in Vista). It beats a manual processor affinity setup almost in every cases, and in those where a manual setup wins the race, it´s by a very short distance.
2.- Even if the OS was a little bit worse in all cases would be advisable to use it, mostly because it´s automatic and you don´t have to worry about your thread´s location
3.- Processor affinity is one of the most important parallelism blockers, so use it if you really need it only, not because you are smarter than Vista. In other words: do not re-invent the wheel. Trust the OS wisdom.
 4.- Windows Vista Scheduler Rocks !


What´s all this information been used for?

Almost one million ray-mesh intersection tests, and what´s this stuff all about? Some people here in Spain says that if it´s white, and comes in a bottle, it´s probably milk… ;)
Massive Ray-Mesh intersection tests + Results stored as 2D table of data = Probably lighting calculations
This are the real results… hope you like it.
 
3darchitecture_chair_low


Take care!

How to download full projects from Google Code, with no SVN clients

This is a short translation of this article, just to make it readable for non-spanish speaking people.

If you want to download full project´s source code from Google Code, you have two options:

  1. Install a SVN client like Tortoise, and learn how to configure it.
  2. Use the DownloadSVN, a very good resource.

Just plug the project´s URL in the window and push “Start”. ¿Which URL? The one found in the “Source” tab at Google Code, like in the following pic.

image

Cómo descargar proyectos enteros de GoogleCode en una patada, sin clientes SVN

[English version here]

Si estás interesado en ver cómo funciona un proyecto alojado en GoogleCode, pero tienes la desgracia de que sea muy grande, la funcionalidad estándar de Browsing a través de su página web se te va a quedar corta. Lo mejor sería que hubiera un botón “Descargar Proyecto”, pero no lo hay. Supongo que pensaron que ya era suficiente ayuda publicar el código fuente… ¡Trabájatelo un poquito niño!.

En fin, que como somos muy vaguetes, pensé que debía haber otra forma, así que seguí el consejo ofrecido aqui, y usé el puto google.

  • Opción 1: Instalar un cliente SVN como Tortoise, y buscar información como ésta sobre cómo usarlo… ufff… mucho curro?
  • Opción 2: Para los super-lazies. Utilizar una herramienta magnífica llamada DownloadSVN.

Solo tienes que decirle la URL del proyecto y ella solita se pone a currar. Lo he probado y funciona mu bien.

Ahora me preguntarás, ¿qué URL es la que tengo que poner?. La que sale en la pestaña “Source” del proyecto en google code, como la de la siguiente foto:

image

Setup TomTom to work with the Samsung Omnia i-900

 

Many people say that it is necessary to install the program GPSFlex to make the TomTom work in the Omnia. This is sometimes true, depending on your Omnia´s ROM, but this program seems to drain off your batteries and to heat your device up. I made a quick test today and with mine, GPSFlex was not necessary at all.

My Omnia comes with the default Orange ROM. What you have to do is:

1.- Configure GPS as: “Other NMEA device”, speed: 4800, COM3. The GPS device should be detected almost immediately.

2.- It sometimes takes 2 or 3 minutes to get a valid GPS signal. If after several minutes it doesn't do it, try switching off your Omnia (with a long push in the power button). After reboot, it should get signal. Some people said that it helps to deactivate your phone before switching off, but this seems a bit weird to me. However, you can try…

Cheers.

Internet Explorer 8 – crash boom bang! -

Yesterday, I installed IE8 (retail version, not beta) in a laptop with the following specs:Ver imagen en tamaño completo

  • Dell M1530
  • 3GB Ram
  • Windows Vista Home Premium SP1

The experience was quite horrible, mostly because:

  • Some add-ons (like Skype) seemed to be incompatible with IE8, what made necessary to update them. That´s quite reasonable, by now, but the worst is yet to come…
  • “Open in new tab” feature didn´t work at all. The tab was opened, but stuck in “connecting…” with no results
  • “Open in new window” feature didn´t work neither. The window was not even open.
  • And what is even more annoying: Installing IE8 interfered  with my Windows Explorer, making it to always open folders in new windows when they were “double-clicked”

And YES, I checked the “Open in new window” and “Open in the same window” folder options were Ok.

After more than half an hour trying to find information, the only suggestion I found was to deactivate all the add-ons installed in Internet Explorer. Is that really a solution? Nevermind, because it it didn´t worked anyway, so…

I uninstalled it (Programs&Features –> Installed Updates) and now everything works like a charm again…

We will have to wait a bit more for it to work properly…

Charla sobre XNA en SecondNug

La peña de SecondNug me ha invitado a dar una charla introductoria a XNA el día 21 de Abril. En ella, desarrollaremos un juego completo desde cero: un clon del Arkanoid, tocando temas como gráficos, sonido, input, animación, etc.

Second NUG: Desarrollo de videojuegos: XNArkanoid

Como todas las charlas de este grupo, se tratará de un WebCast al que podrás unirte a través de Live Meeting. Mas información y registro en el evento aqui y en www.secondnug.com.

Salu2!

Jornadas sobre la profesión de Ingeniero. Universidad pública de Navarra

Next wednesday I´ll be one of the speakers in the conferences about the Engineering studies and careers hosted by the Universidad Pública de Navarra.

----

El próximo miércoles, seré uno de los ponentes en las jornadas sobre la profesión de Ingeniero de la Universidad pública de Navarra.

Aula 4. Edificio el Sario. Pamplona

Texto íntegro:

http://ecodiario.eleconomista.es/espana/noticias/1099078/03/09/La-Universidad-Publica-de-Navarra-organiza-unas-jornadas-sobre-la-profesion-de-ingeniero.html

La Escuela Técnica Superior de Ingenieros Industriales y de Telecomunicaciones de la Universidad Pública de Navarra ha organizado unas jornadas sobre la profesión de ingeniero vista desde sus diferentes especialidades. Las jornadas tendrán lugar los días 17, 18 y 23 de marzo en el Aula 04 de El Sario (Campus de Arrosadia).

PAMPLONA, 14 (EUROPA PRESS)

Las jornadas tienen como objetivo proporcionar un mejor conocimiento de las titulaciones de ingeniero de telecomunicación, informático e industrial tanto a los potenciales alumnos como a la sociedad en general, informó el centro educativo en un comunicado.

La primera de las jornadas estará dedicada al ingeniero de telecomunicaciones y se celebrará el día 17 de 16.30 a 18 horas. En primer lugar se abordará la figura del ingeniero de telecomunicación en el desarrollo futuro de Navarra.

Intervendrán el vicerrector de Investigación de la Universidad Pública de Navarra, Alfonso Carlosena; Cernín Martínez, director general de Política y Promoción Económica del Gobierno de Navarra; Carlos Fernández Valdivieso, vicedecano del Colegio Oficial de Ingenieros de Telecomunicación; y Antonio López Martín, coordinador de Ingeniería de Telecomunicación y subdirector de la Escuela Técnica Superior de Ingenieros Industriales y de Telecomunicación.

A continuación, se desarrollará un mesa redonda sobre la profesión de ingeniero de telecomunicación en la que participarán Oscar Matellanes García, director de Expansión y Negocio de La Información S.A.; Francisco Javier Aranzadi, de Acciona; Joseba Carricas García de la Vega, responsable del área técnica de aplicaciones de Gamesa; Roberto Mercero Igoa, director autonómico de Telefónica en Navarra; y Daniel Lasaosa Medarde, ingeniero de desarrollo en ANIMSA. El moderador será el profesor Antonio López Martín.

Al día siguiente, 18 de marzo, la jornada se centrará en el ingeniero informático y constara de dos charlas. La primera comenzará a las 10 horas y tratará sobre la experiencia personal en el ámbito de la ingeniería informática y correrá a cargo de Iñaki Ayúcar, ingeniero informático y fundador de la empresa Simax Virt S.L., que desarrolla tecnología en el campo de la simulación y ha recibido varios premios como mejor idea de negocio.

En segundo lugar, a las 11.30 horas, se abordará el siguiente tema: 'Inteligencia computacional. Aplicaciones a la industria y a la banca'. Los ponentes serán, por un lado, Francisco Herrera, profesor del Departamento de Ciencias de la Computación e Inteligencia Artificial de la Universidad de Granada, y, por otro, Arantxa Iraizoz, responsable de coordinación de Basilea, de Caja Navarra.

Las jornadas concluirán el 23 de marzo, con una sesión en la que se hablará sobre las aportaciones que pueden ofrecerse en situaciones de crisis, a través de la innovación, desde la profesión de ingeniero industrial.

En la primera parte de la jornada se presentarán iniciativas innovadoras que se están llevando a cabo desde el ámbito de la ingeniería industrial dentro de la Universidad Pública de Navarra. Tal es el caso del proyecto de investigación desarrollado por el Grupo Hidrógeno que ha dado como resultado la transformación, por primera vez en España, de un motor de coche convencional en un motor da coche alimentado por hidrógeno.

Asimismo, se presentará el proyecto de un grupo de estudiantes de ingeniería, que van a diseñar, desarrollar y fabricar una moto de competición, dentro de un concurso internacional (Moto Student) en el que participan universidades de todo el mundo. La segunda parte de la jornada estará dedicada a exponer iniciativas innovadoras en el mundo empresarial relacionadas con la ingeniería industrial.

Easily post VisualStudio formatted source code in your blog

I have posted source code many times before, and always crap-looking. Always wanted to have a copy-paste method to quickly copy source code keeping the format used in Visual Studio. I knew there were tools to do that, but always was too lazy to look for one. Today I did it, and the answer is CSAH: CopySourceAsHtml.

 

It´s a Visual Studio Add-In that offers you a “Copy as HTML” context menu item inside your Visual Studio. You can find it here

 

I have tested it in VStudio 2008, and you can check the results below:

 

 

    public partial class FrmNewDisp : Form

    {

        public FrmNewDisp()

        {

            InitializeComponent();

        }

    }

 

Great!

The tire size mess

A guy asked me a while ago how to read the tire size codes in a wheel. After explaining him, he complained because his results did not match a measurement made on a real wheel. I´ll try to explain why:

205/55R16. What does this mean?

Well, don´t tell me why they did it, but the guys that decided how to code tire sizes made a complete mess around something, in theory, really simple: width, sidewall height and rim diameter. That´s all, but expressed in the most strange and disturbing units they were able to find. It could only be stranger if expressed tire width in light-years…

Tire width: expressed in millimeters. Everything fine by now. Just measure your tire´s width, from a top view, when no load is applied to it.

Tire sidewall height: expressed as a percent of the tire width. So, if the width is 205 mm, a 55% of that (the sidewall height) is 112.75 mm.

Rim diameter: expressed in inches. To translate:

  • inches to meters -> multiply by 0.0254
  • meters to inches –> divide by 0.0254

So, the rim´s diameter will be 406 mm in this case.

An easy calculation: wheel (tire+rim) diameter

If no stress is applied to the wheel, the diameter should be:

Wheel diameter = rim diameter + (sidewall height x 2)

It is important to note that the sidewall height should be multiplied by 2, as it´s the height of one side only (see next picture).

image

Why do I get different results if I measure my tire?

When you take a tape and go out to measure your car´s tires, you will see different results. Specifically in the tire´s sidewall and rim proportion. You should not find any differences in the wheel diameter or radius. Why´s that? Easy… because you are not doing it properly, and this mistake is seen in many places.

The rim diameter should be measured from the inner part where that the tire bead sits on, not from the exterior visible part. So, in order to properly measure the rim size, you will have to take the tire off the rim first, or make an estimation of the amount of tire sidewall that fits inside the rim (usually a bit more than 2 cm, or a bit less that 1 inch).

image

So, measured from the exterior part, with the wheel mounted, we will get at rim (more or less) 2 cm bigger (and of course, 2 cm less of sidewall height).

To know more about tires: The wheel and tire bible

Contribution to SlimDX. UVAtlas wrapper

If you are a .Net developer who wants to deal with 3D Graphics, your best two options are:

  1. Go the XNA way
  2. Use SlimDX 

As all of you probably already know, XNA is a .Net full framework for Game Development. It´s very easy to use, powerful, and cross-platform with the XBox and Zune (too bad no support for Windows Mobile yet). It is great, but in some cases, it has its disadvantages, as being cross-platform introduces some limitations for windows only development.

SlimDX is a DirectX Wrapper to allow .Net developers access the DirectX functionality from C#, Visual Basic, IronPython, etc… It´s a bit more complex, as it just “translates” DirectX to .net, but it is currently the only way to get access to DirectX 10 and DirectX 11 from .Net.

Which way you choose is your business and should depend on many factors. Check the links for more information.

The point is that, due to the problems regarding UVAtlas in Managed DirectX 9 (depicted here), I constributed to the last release (March 2009) of SlimDX with a UVAtlas wrapper for DirectX9, a feature still not present in SlimDX. This implementation fixes the problems present in MDX and explains a bit the meaning of some parameters.

Hope it helps someone.

D3DX UVAtlas for mesh parameterization fails with some meshes (Partition, Pack and Create)

I have been searching for a solution to this situation for a long time. Searched and searched with no luck on the net. I guess that not many people is using the UVAtlas functionality that comes with DirectX9. So, these are my findings:

Partition and Pack always fail?

If you are using the Managed version of DirectX, the Partition and Pack methods will ALWAYS fail. I´m not sure if it´s related to the MDX implementation itself or (as ZMan suggested), may be due to MDX being based on an old version of DirectX. However, if you want to use them, you will have to deal with the native version: D3DXUVAtlasPartition and D3DXUVAtlasPack.

If you have been experiencing random failures in the UVAtlas generation, keep reading:

I have found that the problem is related to the MaxStretch parameter. If you don´t care much about stretching your geometry in the Atlas, the reasonable value is "1" (any amount of stretch allowed), but this value will cause errors with some meshes. I still wasn´t able to detect why and when it fails exactly.

More precisely, what happens then is that Partition method returns wrong values as output texture coordinates, even when returning S_OK as result. If you don´t detect this situation (as D3DXUVAtlasCreate doesn´t) and pass the resulting wrong mesh to the Pack method, it will throw an exception. The worst thing is that this exception is sometimes a native memory violation exception, so a managed try-catch won´t handle it and will force your application to exit.

To detect wrong texture information, Lock the mesh VertexBuffer (to get into its contents) and check for wrong resulting U,V values: +/- infinity, NaN, or extremely big values.

The general criteria to fix this situations is to low MaxStretch down. Most of the times (if not always), using 0.999f instead of 1 makes it, but maybe sometimes you will have to make it even lower, depending on your meshes.

Hope this helps.

Cheers!